diff --git a/packages/@lwc/errors/src/compiler/error-info/index.ts b/packages/@lwc/errors/src/compiler/error-info/index.ts index 5fabfb2949..d8e98789bd 100644 --- a/packages/@lwc/errors/src/compiler/error-info/index.ts +++ b/packages/@lwc/errors/src/compiler/error-info/index.ts @@ -5,7 +5,7 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ /** - * Next error code: 1159 + * Next error code: 1167 */ export * from './compiler'; diff --git a/packages/@lwc/errors/src/compiler/error-info/template-transform.ts b/packages/@lwc/errors/src/compiler/error-info/template-transform.ts index 55c0bc3983..1b56818117 100644 --- a/packages/@lwc/errors/src/compiler/error-info/template-transform.ts +++ b/packages/@lwc/errors/src/compiler/error-info/template-transform.ts @@ -667,4 +667,54 @@ export const ParserDiagnostics = { level: DiagnosticLevel.Error, url: '', }, + IF_BLOCK_DIRECTIVE_SHOULD_BE_EXPRESSION: { + code: 1159, + message: 'lwc:if directive value should be an expression', + level: DiagnosticLevel.Error, + url: '', + }, + ELSEIF_BLOCK_DIRECTIVE_SHOULD_BE_EXPRESSION: { + code: 1160, + message: 'lwc:elseif directive value should be an expression', + level: DiagnosticLevel.Error, + url: '', + }, + ELSE_BLOCK_DIRECTIVE_CANNOT_HAVE_VALUE: { + code: 1161, + message: 'lwc:else directive cannot have a value', + level: DiagnosticLevel.Error, + url: '', + }, + INVALID_IF_BLOCK_DIRECTIVE_WITH_CONDITIONAL: { + code: 1162, + message: "Invalid usage of 'lwc:if' and '{0}' directives on the same element.", + level: DiagnosticLevel.Error, + url: '', + }, + INVALID_ELSEIF_BLOCK_DIRECTIVE_WITH_CONDITIONAL: { + code: 1163, + message: "Invalid usage of 'lwc:elseif' and '{0}' directives on the same element.", + level: DiagnosticLevel.Error, + url: '', + }, + INVALID_ELSE_BLOCK_DIRECTIVE_WITH_CONDITIONAL: { + code: 1164, + message: "Invalid usage of 'lwc:else' and '{0}' directives on the same element.", + level: DiagnosticLevel.Error, + url: '', + }, + LWC_IF_SCOPE_NOT_FOUND: { + code: 1165, + message: + "'{0}' directive must be used immediately after an element with 'lwc:if' or 'lwc:elseif'. No such element found.", + level: DiagnosticLevel.Error, + url: '', + }, + LWC_IF_CANNOT_BE_USED_WITH_IF_DIRECTIVE: { + code: 1166, + message: + "'{0}' directive cannot be used with 'lwc:if', 'lwc:elseif', or 'lwc:else directives on the same element.", + level: DiagnosticLevel.Error, + url: '', + }, }; diff --git a/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/index.spec.js b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/index.spec.js new file mode 100644 index 0000000000..99007ca09b --- /dev/null +++ b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/index.spec.js @@ -0,0 +1,148 @@ +import { createElement } from 'lwc'; +import XComplex from 'x/complex'; +import XTest from 'x/test'; +import XForEach from 'x/forEach'; + +describe('lwc:if, lwc:elseif, lwc:else directives', () => { + it('should render if branch if the value for lwc:if is truthy', () => { + const elm = createElement('x-test', { is: XTest }); + elm.showIf = true; + document.body.appendChild(elm); + + expect(elm.shadowRoot.querySelector('.if')).not.toBeNull(); + }); + + it('should render elseif branch if the value for lwc:if is falsy and the value for lwc:elseif is truthy', () => { + const elm = createElement('x-test', { is: XTest }); + elm.showElseif = true; + document.body.appendChild(elm); + + expect(elm.shadowRoot.querySelector('.elseif')).not.toBeNull(); + }); + + it('should render else branch if the values for lwc:if and lwc:elseif are all falsy', () => { + const elm = createElement('x-test', { is: XTest }); + document.body.appendChild(elm); + + expect(elm.shadowRoot.querySelector('.else')).not.toBeNull(); + }); + + it('should update which branch is rendered if the value changes', () => { + const elm = createElement('x-test', { is: XTest }); + elm.showIf = true; + document.body.appendChild(elm); + + expect(elm.shadowRoot.querySelector('.if')).not.toBeNull(); + + elm.showIf = false; + return Promise.resolve() + .then(() => { + expect(elm.shadowRoot.querySelector('.else')).not.toBeNull(); + elm.showElseif = true; + }) + .then(() => { + expect(elm.shadowRoot.querySelector('.elseif')).not.toBeNull(); + elm.showIf = true; + }) + .then(() => { + expect(elm.shadowRoot.querySelector('.if')).not.toBeNull(); + }); + }); + + it('should render content when nested inside another if branch', () => { + const element = createElement('x-complex', { is: XComplex }); + element.showNestedContent = true; + document.body.appendChild(element); + + expect(element.shadowRoot.querySelector('.nestedContent')).not.toBeNull(); + }); + + it('should rerender content when nested inside another if branch', () => { + const element = createElement('x-complex', { is: XComplex }); + document.body.appendChild(element); + + expect(element.shadowRoot.querySelector('.nestedElse')).not.toBeNull(); + + element.showNestedContent = true; + return Promise.resolve().then(() => { + expect(element.shadowRoot.querySelector('.nestedContent')).not.toBeNull(); + }); + }); + + it('should render list content properly', () => { + const element = createElement('x-complex', { is: XComplex }); + element.showList = true; + document.body.appendChild(element); + + expect(element.shadowRoot.querySelector('.if').textContent).toBe('123'); + }); + + it('should rerender list content when updated', () => { + const element = createElement('x-for-each', { is: XForEach }); + element.showList = true; + document.body.appendChild(element); + + expect(element.shadowRoot.querySelector('.if').textContent).toBe('123'); + + element.appendToList({ + value: 4, + show: true, + }); + + return Promise.resolve() + .then(() => { + expect(element.shadowRoot.querySelector('.if').textContent).toBe('1234'); + + element.showList = false; + element.appendToList({ + value: 5, + show: true, + }); + element.prependToList({ + value: 0, + show: true, + }); + }) + .then(() => { + expect(element.shadowRoot.querySelector('.if')).toBeNull(); + + element.showList = true; + }) + .then(() => { + expect(element.shadowRoot.querySelector('.if').textContent).toBe('012345'); + }); + }); + + it('should rerender list items when conditional expressions change', () => { + const element = createElement('x-for-each', { is: XForEach }); + element.showList = true; + document.body.appendChild(element); + + expect(element.shadowRoot.querySelector('.if').textContent).toBe('123'); + + element.appendToList({ + value: 4, + show: false, + }); + + return Promise.resolve() + .then(() => { + expect(element.shadowRoot.querySelector('.if').textContent).toBe('123'); + + element.show(4); + }) + .then(() => { + expect(element.shadowRoot.querySelector('.if').textContent).toBe('1234'); + + element.hide(1); + element.hide(3); + element.prependToList({ + value: 0, + show: true, + }); + }) + .then(() => { + expect(element.shadowRoot.querySelector('.if').textContent).toBe('024'); + }); + }); +}); diff --git a/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/complex/complex.html b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/complex/complex.html new file mode 100644 index 0000000000..8c3513b3a6 --- /dev/null +++ b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/complex/complex.html @@ -0,0 +1,18 @@ + diff --git a/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/complex/complex.js b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/complex/complex.js new file mode 100644 index 0000000000..6cf814e641 --- /dev/null +++ b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/complex/complex.js @@ -0,0 +1,7 @@ +import { LightningElement, api, track } from 'lwc'; + +export default class Complex extends LightningElement { + @api showNestedContent = false; + @api showList = false; + @track items = [1, 2, 3]; +} diff --git a/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/forEach/forEach.html b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/forEach/forEach.html new file mode 100644 index 0000000000..32272a3cbd --- /dev/null +++ b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/forEach/forEach.html @@ -0,0 +1,9 @@ + diff --git a/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/forEach/forEach.js b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/forEach/forEach.js new file mode 100644 index 0000000000..3a995b2f2e --- /dev/null +++ b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/forEach/forEach.js @@ -0,0 +1,34 @@ +import { LightningElement, api, track } from 'lwc'; + +export default class ForEach extends LightningElement { + @api showList = false; + @track items = [ + { value: 1, show: true }, + { value: 2, show: true }, + { value: 3, show: true }, + ]; + + @api + appendToList(value) { + this.items.push(value); + } + + @api + prependToList(value) { + this.items.splice(0, 0, value); + } + + @api + hide(value) { + this.find(value).show = false; + } + + @api + show(value) { + this.find(value).show = true; + } + + find(value) { + return this.items.find((item) => item.value === value); + } +} diff --git a/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/test/test.html b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/test/test.html new file mode 100644 index 0000000000..58c7e0d98c --- /dev/null +++ b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/test/test.html @@ -0,0 +1,11 @@ + diff --git a/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/test/test.js b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/test/test.js new file mode 100644 index 0000000000..badbf36f7c --- /dev/null +++ b/packages/@lwc/integration-karma/test/template/directive-if-elseif-else/x/test/test.js @@ -0,0 +1,6 @@ +import { LightningElement, api } from 'lwc'; + +export default class Test extends LightningElement { + @api showIf = false; + @api showElseif = false; +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/actual.html new file mode 100644 index 0000000000..57da882db9 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/actual.html @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/ast.json new file mode 100644 index 0000000000..7c471781f1 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/ast.json @@ -0,0 +1,330 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 6, + "endColumn": 12, + "start": 0, + "end": 212, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 6, + "startColumn": 1, + "endLine": 6, + "endColumn": 12, + "start": 201, + "end": 212 + } + }, + "directives": [], + "children": [ + { + "type": "ForEach", + "expression": { + "type": "Identifier", + "start": 1, + "end": 6, + "name": "items", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "item": { + "type": "Identifier", + "name": "item", + "location": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 47, + "start": 42, + "end": 57 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 5, + "endColumn": 16, + "start": 15, + "end": 200 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 13, + "object": { + "type": "Identifier", + "start": 1, + "end": 5, + "name": "item" + }, + "property": { + "type": "Identifier", + "start": 6, + "end": 13, + "name": "visible" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 3, + "startColumn": 14, + "endLine": 3, + "endColumn": 35, + "start": 72, + "end": 93 + } + }, + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 78, + "start": 67, + "end": 136 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 14, + "endLine": 3, + "endColumn": 35, + "start": 72, + "end": 93 + }, + "children": [ + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 78, + "start": 67, + "end": 136, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 51, + "start": 67, + "end": 109 + }, + "endTag": { + "startLine": 3, + "startColumn": 72, + "endLine": 3, + "endColumn": 78, + "start": 130, + "end": 136 + } + }, + "attributes": [], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "Key", + "value": { + "type": "MemberExpression", + "start": 1, + "end": 9, + "object": { + "type": "Identifier", + "start": 1, + "end": 5, + "name": "item" + }, + "property": { + "type": "Identifier", + "start": 6, + "end": 9, + "name": "key" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 3, + "startColumn": 36, + "endLine": 3, + "endColumn": 50, + "start": 94, + "end": 108 + } + }, + "location": { + "startLine": 3, + "startColumn": 36, + "endLine": 3, + "endColumn": 50, + "start": 94, + "end": 108 + } + } + ], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Conditional Iteration", + "value": { + "type": "Literal", + "value": "Conditional Iteration" + }, + "location": { + "startLine": 3, + "startColumn": 51, + "endLine": 3, + "endColumn": 72, + "start": 109, + "end": 130 + } + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 4, + "startColumn": 9, + "endLine": 4, + "endColumn": 48, + "start": 145, + "end": 184 + }, + "directiveLocation": { + "startLine": 4, + "startColumn": 14, + "endLine": 4, + "endColumn": 22, + "start": 150, + "end": 158 + }, + "children": [ + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 4, + "startColumn": 9, + "endLine": 4, + "endColumn": 48, + "start": 145, + "end": 184, + "startTag": { + "startLine": 4, + "startColumn": 9, + "endLine": 4, + "endColumn": 38, + "start": 145, + "end": 174 + }, + "endTag": { + "startLine": 4, + "startColumn": 42, + "endLine": 4, + "endColumn": 48, + "start": 178, + "end": 184 + } + }, + "attributes": [], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "Key", + "value": { + "type": "MemberExpression", + "start": 1, + "end": 9, + "object": { + "type": "Identifier", + "start": 1, + "end": 5, + "name": "item" + }, + "property": { + "type": "Identifier", + "start": 6, + "end": 9, + "name": "key" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 4, + "startColumn": 23, + "endLine": 4, + "endColumn": 37, + "start": 159, + "end": 173 + } + }, + "location": { + "startLine": 4, + "startColumn": 23, + "endLine": 4, + "endColumn": 37, + "start": 159, + "end": 173 + } + } + ], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Else", + "value": { + "type": "Literal", + "value": "Else" + }, + "location": { + "startLine": 4, + "startColumn": 38, + "endLine": 4, + "endColumn": 42, + "start": 174, + "end": 178 + } + } + ] + } + ] + } + } + ] + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/expected.js new file mode 100644 index 0000000000..cad16128b5 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/expected.js @@ -0,0 +1,42 @@ +import { registerTemplate } from "lwc"; +function tmpl($api, $cmp, $slotset, $ctx) { + const { + k: api_key, + t: api_text, + h: api_element, + fr: api_fragment, + i: api_iterator, + } = $api; + return api_iterator($cmp.items, function (item) { + return item.visible + ? api_fragment( + 0, + [ + api_element( + "div", + { + key: api_key(1, item.key), + }, + [api_text("Conditional Iteration")] + ), + ], + 0 + ) + : api_fragment( + 0, + [ + api_element( + "div", + { + key: api_key(2, item.key), + }, + [api_text("Else")] + ), + ], + 0 + ); + }); + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/html-elements/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/actual.html new file mode 100644 index 0000000000..1ee755b7d2 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/actual.html @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/ast.json new file mode 100644 index 0000000000..f075473a3e --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/ast.json @@ -0,0 +1,330 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 10, + "endColumn": 12, + "start": 0, + "end": 298, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 10, + "startColumn": 1, + "endLine": 10, + "endColumn": 12, + "start": 287, + "end": 298 + } + }, + "directives": [], + "children": [ + { + "type": "ForEach", + "expression": { + "type": "Identifier", + "start": 1, + "end": 6, + "name": "items", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "item": { + "type": "Identifier", + "name": "item", + "location": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 47, + "start": 42, + "end": 57 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 9, + "endColumn": 16, + "start": 15, + "end": 286 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 13, + "object": { + "type": "Identifier", + "start": 1, + "end": 5, + "name": "item" + }, + "property": { + "type": "Identifier", + "start": 6, + "end": 13, + "name": "visible" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 3, + "startColumn": 19, + "endLine": 3, + "endColumn": 40, + "start": 77, + "end": 98 + } + }, + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 5, + "endColumn": 20, + "start": 67, + "end": 179 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 19, + "endLine": 3, + "endColumn": 40, + "start": 77, + "end": 98 + }, + "children": [ + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 4, + "startColumn": 13, + "endLine": 4, + "endColumn": 60, + "start": 112, + "end": 159, + "startTag": { + "startLine": 4, + "startColumn": 13, + "endLine": 4, + "endColumn": 33, + "start": 112, + "end": 132 + }, + "endTag": { + "startLine": 4, + "startColumn": 54, + "endLine": 4, + "endColumn": 60, + "start": 153, + "end": 159 + } + }, + "attributes": [], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "Key", + "value": { + "type": "MemberExpression", + "start": 1, + "end": 9, + "object": { + "type": "Identifier", + "start": 1, + "end": 5, + "name": "item" + }, + "property": { + "type": "Identifier", + "start": 6, + "end": 9, + "name": "key" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 4, + "startColumn": 18, + "endLine": 4, + "endColumn": 32, + "start": 117, + "end": 131 + } + }, + "location": { + "startLine": 4, + "startColumn": 18, + "endLine": 4, + "endColumn": 32, + "start": 117, + "end": 131 + } + } + ], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Conditional Iteration", + "value": { + "type": "Literal", + "value": "Conditional Iteration" + }, + "location": { + "startLine": 4, + "startColumn": 33, + "endLine": 4, + "endColumn": 54, + "start": 132, + "end": 153 + } + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 6, + "startColumn": 9, + "endLine": 8, + "endColumn": 20, + "start": 188, + "end": 270 + }, + "directiveLocation": { + "startLine": 6, + "startColumn": 19, + "endLine": 6, + "endColumn": 27, + "start": 198, + "end": 206 + }, + "children": [ + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 7, + "startColumn": 13, + "endLine": 7, + "endColumn": 43, + "start": 220, + "end": 250, + "startTag": { + "startLine": 7, + "startColumn": 13, + "endLine": 7, + "endColumn": 33, + "start": 220, + "end": 240 + }, + "endTag": { + "startLine": 7, + "startColumn": 37, + "endLine": 7, + "endColumn": 43, + "start": 244, + "end": 250 + } + }, + "attributes": [], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "Key", + "value": { + "type": "MemberExpression", + "start": 1, + "end": 9, + "object": { + "type": "Identifier", + "start": 1, + "end": 5, + "name": "item" + }, + "property": { + "type": "Identifier", + "start": 6, + "end": 9, + "name": "key" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 7, + "startColumn": 18, + "endLine": 7, + "endColumn": 32, + "start": 225, + "end": 239 + } + }, + "location": { + "startLine": 7, + "startColumn": 18, + "endLine": 7, + "endColumn": 32, + "start": 225, + "end": 239 + } + } + ], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Else", + "value": { + "type": "Literal", + "value": "Else" + }, + "location": { + "startLine": 7, + "startColumn": 33, + "endLine": 7, + "endColumn": 37, + "start": 240, + "end": 244 + } + } + ] + } + ] + } + } + ] + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/expected.js new file mode 100644 index 0000000000..cad16128b5 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/expected.js @@ -0,0 +1,42 @@ +import { registerTemplate } from "lwc"; +function tmpl($api, $cmp, $slotset, $ctx) { + const { + k: api_key, + t: api_text, + h: api_element, + fr: api_fragment, + i: api_iterator, + } = $api; + return api_iterator($cmp.items, function (item) { + return item.visible + ? api_fragment( + 0, + [ + api_element( + "div", + { + key: api_key(1, item.key), + }, + [api_text("Conditional Iteration")] + ), + ], + 0 + ) + : api_fragment( + 0, + [ + api_element( + "div", + { + key: api_key(2, item.key), + }, + [api_text("Else")] + ), + ], + 0 + ); + }); + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/directive-for-each/template/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/actual.html new file mode 100644 index 0000000000..a3d75e2fa2 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/actual.html @@ -0,0 +1,8 @@ + diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/ast.json new file mode 100644 index 0000000000..932249530f --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/ast.json @@ -0,0 +1,244 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 8, + "endColumn": 12, + "start": 0, + "end": 197, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 8, + "startColumn": 1, + "endLine": 8, + "endColumn": 12, + "start": 186, + "end": 197 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 11, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 9, + "end": 11, + "name": "if" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 34, + "start": 25, + "end": 44 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 4, + "endColumn": 16, + "start": 15, + "end": 91 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 34, + "start": 25, + "end": 44 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 30, + "start": 54, + "end": 75, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 13, + "start": 54, + "end": 58 + }, + "endTag": { + "startLine": 3, + "startColumn": 25, + "endLine": 3, + "endColumn": 30, + "start": 70, + "end": 75 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "if condition", + "value": { + "type": "Literal", + "value": "if condition" + }, + "location": { + "startLine": 3, + "startColumn": 13, + "endLine": 3, + "endColumn": 25, + "start": 58, + "end": 70 + } + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 5, + "startColumn": 5, + "endLine": 7, + "endColumn": 16, + "start": 96, + "end": 185 + }, + "directiveLocation": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 23, + "start": 106, + "end": 114 + }, + "children": [ + { + "type": "Component", + "name": "x-foo", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 54, + "start": 124, + "end": 169, + "startTag": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 46, + "start": 124, + "end": 161 + }, + "endTag": { + "startLine": 6, + "startColumn": 46, + "endLine": 6, + "endColumn": 54, + "start": 161, + "end": 169 + } + }, + "attributes": [], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "Dynamic", + "value": { + "type": "MemberExpression", + "start": 1, + "end": 16, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 12, + "name": "trackedProp" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 13, + "end": 16, + "name": "foo" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 6, + "startColumn": 16, + "endLine": 6, + "endColumn": 45, + "start": 131, + "end": 160 + } + }, + "location": { + "startLine": 6, + "startColumn": 16, + "endLine": 6, + "endColumn": 45, + "start": 131, + "end": 160 + } + } + ], + "listeners": [], + "children": [] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/config.json new file mode 100644 index 0000000000..7fa4e84f22 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/config.json @@ -0,0 +1,3 @@ +{ + "experimentalDynamicDirective": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/expected.js new file mode 100644 index 0000000000..ea77c14fa2 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/expected.js @@ -0,0 +1,24 @@ +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment`if condition`; +const stc0 = { + key: 3, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { + st: api_static_fragment, + fr: api_fragment, + dc: api_dynamic_component, + } = $api; + return [ + $cmp.visible.if + ? api_fragment(0, [api_static_fragment($fragment1(), 2)], 0) + : api_fragment( + 0, + [api_dynamic_component("x-foo", $cmp.trackedProp.foo, stc0)], + 0 + ), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-else/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/actual.html new file mode 100644 index 0000000000..9f8792a358 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/actual.html @@ -0,0 +1,25 @@ + diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/ast.json new file mode 100644 index 0000000000..8af00dffd0 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/ast.json @@ -0,0 +1,805 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 25, + "endColumn": 12, + "start": 0, + "end": 701, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 25, + "startColumn": 1, + "endLine": 25, + "endColumn": 12, + "start": 690, + "end": 701 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 9, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 6, + "name": "outer" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 7, + "end": 9, + "name": "if" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 32, + "start": 25, + "end": 42 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 4, + "endColumn": 16, + "start": 15, + "end": 85 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 32, + "start": 25, + "end": 42 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 26, + "start": 52, + "end": 69, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 13, + "start": 52, + "end": 56 + }, + "endTag": { + "startLine": 3, + "startColumn": 21, + "endLine": 3, + "endColumn": 26, + "start": 64, + "end": 69 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "outer if", + "value": { + "type": "Literal", + "value": "outer if" + }, + "location": { + "startLine": 3, + "startColumn": 13, + "endLine": 3, + "endColumn": 21, + "start": 56, + "end": 64 + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 14, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 6, + "name": "outer" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 7, + "end": 14, + "name": "elseif1" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 41, + "start": 100, + "end": 126 + } + }, + "location": { + "startLine": 5, + "startColumn": 5, + "endLine": 7, + "endColumn": 16, + "start": 90, + "end": 173 + }, + "directiveLocation": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 41, + "start": 100, + "end": 126 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 30, + "start": 136, + "end": 157, + "startTag": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 13, + "start": 136, + "end": 140 + }, + "endTag": { + "startLine": 6, + "startColumn": 25, + "endLine": 6, + "endColumn": 30, + "start": 152, + "end": 157 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "outer elseif", + "value": { + "type": "Literal", + "value": "outer elseif" + }, + "location": { + "startLine": 6, + "startColumn": 13, + "endLine": 6, + "endColumn": 25, + "start": 140, + "end": 152 + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 14, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 6, + "name": "outer" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 7, + "end": 14, + "name": "elseif2" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 8, + "startColumn": 15, + "endLine": 8, + "endColumn": 41, + "start": 188, + "end": 214 + } + }, + "location": { + "startLine": 8, + "startColumn": 5, + "endLine": 21, + "endColumn": 16, + "start": 178, + "end": 621 + }, + "directiveLocation": { + "startLine": 8, + "startColumn": 15, + "endLine": 8, + "endColumn": 41, + "start": 188, + "end": 214 + }, + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 9, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 6, + "name": "inner" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 7, + "end": 9, + "name": "if" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 9, + "startColumn": 19, + "endLine": 9, + "endColumn": 36, + "start": 234, + "end": 251 + } + }, + "location": { + "startLine": 9, + "startColumn": 9, + "endLine": 11, + "endColumn": 20, + "start": 224, + "end": 302 + }, + "directiveLocation": { + "startLine": 9, + "startColumn": 19, + "endLine": 9, + "endColumn": 36, + "start": 234, + "end": 251 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 10, + "startColumn": 13, + "endLine": 10, + "endColumn": 30, + "start": 265, + "end": 282, + "startTag": { + "startLine": 10, + "startColumn": 13, + "endLine": 10, + "endColumn": 17, + "start": 265, + "end": 269 + }, + "endTag": { + "startLine": 10, + "startColumn": 25, + "endLine": 10, + "endColumn": 30, + "start": 277, + "end": 282 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "inner if", + "value": { + "type": "Literal", + "value": "inner if" + }, + "location": { + "startLine": 10, + "startColumn": 17, + "endLine": 10, + "endColumn": 25, + "start": 269, + "end": 277 + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 13, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 6, + "name": "inner" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 7, + "end": 13, + "name": "elseif" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 12, + "startColumn": 19, + "endLine": 12, + "endColumn": 44, + "start": 321, + "end": 346 + } + }, + "location": { + "startLine": 12, + "startColumn": 9, + "endLine": 14, + "endColumn": 20, + "start": 311, + "end": 401 + }, + "directiveLocation": { + "startLine": 12, + "startColumn": 19, + "endLine": 12, + "endColumn": 44, + "start": 321, + "end": 346 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 13, + "startColumn": 13, + "endLine": 13, + "endColumn": 34, + "start": 360, + "end": 381, + "startTag": { + "startLine": 13, + "startColumn": 13, + "endLine": 13, + "endColumn": 17, + "start": 360, + "end": 364 + }, + "endTag": { + "startLine": 13, + "startColumn": 29, + "endLine": 13, + "endColumn": 34, + "start": 376, + "end": 381 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "inner elseif", + "value": { + "type": "Literal", + "value": "inner elseif" + }, + "location": { + "startLine": 13, + "startColumn": 17, + "endLine": 13, + "endColumn": 29, + "start": 364, + "end": 376 + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 14, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 6, + "name": "inner" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 7, + "end": 14, + "name": "elseif2" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 15, + "startColumn": 19, + "endLine": 15, + "endColumn": 45, + "start": 420, + "end": 446 + } + }, + "location": { + "startLine": 15, + "startColumn": 9, + "endLine": 17, + "endColumn": 20, + "start": 410, + "end": 525 + }, + "directiveLocation": { + "startLine": 15, + "startColumn": 19, + "endLine": 15, + "endColumn": 45, + "start": 420, + "end": 446 + }, + "children": [ + { + "type": "Component", + "name": "x-foo", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 16, + "startColumn": 13, + "endLine": 16, + "endColumn": 58, + "start": 460, + "end": 505, + "startTag": { + "startLine": 16, + "startColumn": 13, + "endLine": 16, + "endColumn": 50, + "start": 460, + "end": 497 + }, + "endTag": { + "startLine": 16, + "startColumn": 50, + "endLine": 16, + "endColumn": 58, + "start": 497, + "end": 505 + } + }, + "attributes": [], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "Dynamic", + "value": { + "type": "MemberExpression", + "start": 1, + "end": 16, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 12, + "name": "trackedProp" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 13, + "end": 16, + "name": "foo" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 16, + "startColumn": 20, + "endLine": 16, + "endColumn": 49, + "start": 467, + "end": 496 + } + }, + "location": { + "startLine": 16, + "startColumn": 20, + "endLine": 16, + "endColumn": 49, + "start": 467, + "end": 496 + } + } + ], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 18, + "startColumn": 9, + "endLine": 20, + "endColumn": 20, + "start": 534, + "end": 605 + }, + "directiveLocation": { + "startLine": 18, + "startColumn": 19, + "endLine": 18, + "endColumn": 27, + "start": 544, + "end": 552 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 19, + "startColumn": 13, + "endLine": 19, + "endColumn": 32, + "start": 566, + "end": 585, + "startTag": { + "startLine": 19, + "startColumn": 13, + "endLine": 19, + "endColumn": 17, + "start": 566, + "end": 570 + }, + "endTag": { + "startLine": 19, + "startColumn": 27, + "endLine": 19, + "endColumn": 32, + "start": 580, + "end": 585 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "inner else", + "value": { + "type": "Literal", + "value": "inner else" + }, + "location": { + "startLine": 19, + "startColumn": 17, + "endLine": 19, + "endColumn": 27, + "start": 570, + "end": 580 + } + } + ] + } + ] + } + } + } + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 22, + "startColumn": 5, + "endLine": 24, + "endColumn": 16, + "start": 626, + "end": 689 + }, + "directiveLocation": { + "startLine": 22, + "startColumn": 15, + "endLine": 22, + "endColumn": 23, + "start": 636, + "end": 644 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 23, + "startColumn": 9, + "endLine": 23, + "endColumn": 28, + "start": 654, + "end": 673, + "startTag": { + "startLine": 23, + "startColumn": 9, + "endLine": 23, + "endColumn": 13, + "start": 654, + "end": 658 + }, + "endTag": { + "startLine": 23, + "startColumn": 23, + "endLine": 23, + "endColumn": 28, + "start": 668, + "end": 673 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "outer else", + "value": { + "type": "Literal", + "value": "outer else" + }, + "location": { + "startLine": 23, + "startColumn": 13, + "endLine": 23, + "endColumn": 23, + "start": 658, + "end": 668 + } + } + ] + } + ] + } + } + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/config.json new file mode 100644 index 0000000000..7fa4e84f22 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/config.json @@ -0,0 +1,3 @@ +{ + "experimentalDynamicDirective": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/expected.js new file mode 100644 index 0000000000..7419f0a850 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/expected.js @@ -0,0 +1,45 @@ +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment`outer if`; +const $fragment2 = parseFragment`outer elseif`; +const $fragment3 = parseFragment`inner if`; +const $fragment4 = parseFragment`inner elseif`; +const $fragment5 = parseFragment`inner else`; +const $fragment6 = parseFragment`outer else`; +const stc0 = { + key: 10, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { + st: api_static_fragment, + fr: api_fragment, + dc: api_dynamic_component, + } = $api; + return [ + $cmp.outer.if + ? api_fragment(0, [api_static_fragment($fragment1(), 2)], 0) + : $cmp.outer.elseif1 + ? api_fragment(0, [api_static_fragment($fragment2(), 4)], 0) + : $cmp.outer.elseif2 + ? api_fragment( + 0, + [ + $cmp.inner.if + ? api_fragment(5, [api_static_fragment($fragment3(), 7)], 0) + : $cmp.inner.elseif + ? api_fragment(5, [api_static_fragment($fragment4(), 9)], 0) + : $cmp.inner.elseif2 + ? api_fragment( + 5, + [api_dynamic_component("x-foo", $cmp.trackedProp.foo, stc0)], + 0 + ) + : api_fragment(5, [api_static_fragment($fragment5(), 12)], 0), + ], + 0 + ) + : api_fragment(0, [api_static_fragment($fragment6(), 14)], 0), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else-nested/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/actual.html new file mode 100644 index 0000000000..224e213de0 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/actual.html @@ -0,0 +1,11 @@ + diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/ast.json new file mode 100644 index 0000000000..ef7116dd1e --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/ast.json @@ -0,0 +1,352 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 11, + "endColumn": 12, + "start": 0, + "end": 290, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 11, + "startColumn": 1, + "endLine": 11, + "endColumn": 12, + "start": 279, + "end": 290 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 11, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 9, + "end": 11, + "name": "if" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 34, + "start": 25, + "end": 44 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 4, + "endColumn": 16, + "start": 15, + "end": 91 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 34, + "start": 25, + "end": 44 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 30, + "start": 54, + "end": 75, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 13, + "start": 54, + "end": 58 + }, + "endTag": { + "startLine": 3, + "startColumn": 25, + "endLine": 3, + "endColumn": 30, + "start": 70, + "end": 75 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "if condition", + "value": { + "type": "Literal", + "value": "if condition" + }, + "location": { + "startLine": 3, + "startColumn": 13, + "endLine": 3, + "endColumn": 25, + "start": 58, + "end": 70 + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 15, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 9, + "end": 15, + "name": "elseif" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 42, + "start": 106, + "end": 133 + } + }, + "location": { + "startLine": 5, + "startColumn": 5, + "endLine": 7, + "endColumn": 16, + "start": 96, + "end": 184 + }, + "directiveLocation": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 42, + "start": 106, + "end": 133 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 34, + "start": 143, + "end": 168, + "startTag": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 13, + "start": 143, + "end": 147 + }, + "endTag": { + "startLine": 6, + "startColumn": 29, + "endLine": 6, + "endColumn": 34, + "start": 163, + "end": 168 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "elseif condition", + "value": { + "type": "Literal", + "value": "elseif condition" + }, + "location": { + "startLine": 6, + "startColumn": 13, + "endLine": 6, + "endColumn": 29, + "start": 147, + "end": 163 + } + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 8, + "startColumn": 5, + "endLine": 10, + "endColumn": 16, + "start": 189, + "end": 278 + }, + "directiveLocation": { + "startLine": 8, + "startColumn": 15, + "endLine": 8, + "endColumn": 23, + "start": 199, + "end": 207 + }, + "children": [ + { + "type": "Component", + "name": "x-foo", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 9, + "startColumn": 9, + "endLine": 9, + "endColumn": 54, + "start": 217, + "end": 262, + "startTag": { + "startLine": 9, + "startColumn": 9, + "endLine": 9, + "endColumn": 46, + "start": 217, + "end": 254 + }, + "endTag": { + "startLine": 9, + "startColumn": 46, + "endLine": 9, + "endColumn": 54, + "start": 254, + "end": 262 + } + }, + "attributes": [], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "Dynamic", + "value": { + "type": "MemberExpression", + "start": 1, + "end": 16, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 12, + "name": "trackedProp" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 13, + "end": 16, + "name": "foo" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 9, + "startColumn": 16, + "endLine": 9, + "endColumn": 45, + "start": 224, + "end": 253 + } + }, + "location": { + "startLine": 9, + "startColumn": 16, + "endLine": 9, + "endColumn": 45, + "start": 224, + "end": 253 + } + } + ], + "listeners": [], + "children": [] + } + ] + } + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/config.json new file mode 100644 index 0000000000..7fa4e84f22 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/config.json @@ -0,0 +1,3 @@ +{ + "experimentalDynamicDirective": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/expected.js new file mode 100644 index 0000000000..f7072d9d04 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/expected.js @@ -0,0 +1,27 @@ +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment`if condition`; +const $fragment2 = parseFragment`elseif condition`; +const stc0 = { + key: 5, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { + st: api_static_fragment, + fr: api_fragment, + dc: api_dynamic_component, + } = $api; + return [ + $cmp.visible.if + ? api_fragment(0, [api_static_fragment($fragment1(), 2)], 0) + : $cmp.visible.elseif + ? api_fragment(0, [api_static_fragment($fragment2(), 4)], 0) + : api_fragment( + 0, + [api_dynamic_component("x-foo", $cmp.trackedProp.foo, stc0)], + 0 + ), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-else/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/actual.html new file mode 100644 index 0000000000..b53d706472 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/actual.html @@ -0,0 +1,14 @@ + diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/ast.json new file mode 100644 index 0000000000..4298b72df6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/ast.json @@ -0,0 +1,460 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 14, + "endColumn": 12, + "start": 0, + "end": 382, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 14, + "startColumn": 1, + "endLine": 14, + "endColumn": 12, + "start": 371, + "end": 382 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 11, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 9, + "end": 11, + "name": "if" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 34, + "start": 25, + "end": 44 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 4, + "endColumn": 16, + "start": 15, + "end": 91 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 34, + "start": 25, + "end": 44 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 30, + "start": 54, + "end": 75, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 13, + "start": 54, + "end": 58 + }, + "endTag": { + "startLine": 3, + "startColumn": 25, + "endLine": 3, + "endColumn": 30, + "start": 70, + "end": 75 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "if condition", + "value": { + "type": "Literal", + "value": "if condition" + }, + "location": { + "startLine": 3, + "startColumn": 13, + "endLine": 3, + "endColumn": 25, + "start": 58, + "end": 70 + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 15, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 9, + "end": 15, + "name": "elseif" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 42, + "start": 106, + "end": 133 + } + }, + "location": { + "startLine": 5, + "startColumn": 5, + "endLine": 7, + "endColumn": 16, + "start": 96, + "end": 184 + }, + "directiveLocation": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 42, + "start": 106, + "end": 133 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 34, + "start": 143, + "end": 168, + "startTag": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 13, + "start": 143, + "end": 147 + }, + "endTag": { + "startLine": 6, + "startColumn": 29, + "endLine": 6, + "endColumn": 34, + "start": 163, + "end": 168 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "elseif condition", + "value": { + "type": "Literal", + "value": "elseif condition" + }, + "location": { + "startLine": 6, + "startColumn": 13, + "endLine": 6, + "endColumn": 29, + "start": 147, + "end": 163 + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 16, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 9, + "end": 16, + "name": "elseif2" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 8, + "startColumn": 15, + "endLine": 8, + "endColumn": 43, + "start": 199, + "end": 227 + } + }, + "location": { + "startLine": 8, + "startColumn": 5, + "endLine": 10, + "endColumn": 16, + "start": 189, + "end": 298 + }, + "directiveLocation": { + "startLine": 8, + "startColumn": 15, + "endLine": 8, + "endColumn": 43, + "start": 199, + "end": 227 + }, + "children": [ + { + "type": "Component", + "name": "x-foo", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 9, + "startColumn": 9, + "endLine": 9, + "endColumn": 54, + "start": 237, + "end": 282, + "startTag": { + "startLine": 9, + "startColumn": 9, + "endLine": 9, + "endColumn": 46, + "start": 237, + "end": 274 + }, + "endTag": { + "startLine": 9, + "startColumn": 46, + "endLine": 9, + "endColumn": 54, + "start": 274, + "end": 282 + } + }, + "attributes": [], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "Dynamic", + "value": { + "type": "MemberExpression", + "start": 1, + "end": 16, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 12, + "name": "trackedProp" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 13, + "end": 16, + "name": "foo" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 9, + "startColumn": 16, + "endLine": 9, + "endColumn": 45, + "start": 244, + "end": 273 + } + }, + "location": { + "startLine": 9, + "startColumn": 16, + "endLine": 9, + "endColumn": 45, + "start": 244, + "end": 273 + } + } + ], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 11, + "startColumn": 5, + "endLine": 13, + "endColumn": 16, + "start": 303, + "end": 370 + }, + "directiveLocation": { + "startLine": 11, + "startColumn": 15, + "endLine": 11, + "endColumn": 23, + "start": 313, + "end": 321 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 12, + "startColumn": 9, + "endLine": 12, + "endColumn": 32, + "start": 331, + "end": 354, + "startTag": { + "startLine": 12, + "startColumn": 9, + "endLine": 12, + "endColumn": 13, + "start": 331, + "end": 335 + }, + "endTag": { + "startLine": 12, + "startColumn": 27, + "endLine": 12, + "endColumn": 32, + "start": 349, + "end": 354 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "else condition", + "value": { + "type": "Literal", + "value": "else condition" + }, + "location": { + "startLine": 12, + "startColumn": 13, + "endLine": 12, + "endColumn": 27, + "start": 335, + "end": 349 + } + } + ] + } + ] + } + } + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/config.json new file mode 100644 index 0000000000..7fa4e84f22 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/config.json @@ -0,0 +1,3 @@ +{ + "experimentalDynamicDirective": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/expected.js new file mode 100644 index 0000000000..18fc0112f3 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/expected.js @@ -0,0 +1,30 @@ +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment`if condition`; +const $fragment2 = parseFragment`elseif condition`; +const $fragment3 = parseFragment`else condition`; +const stc0 = { + key: 5, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { + st: api_static_fragment, + fr: api_fragment, + dc: api_dynamic_component, + } = $api; + return [ + $cmp.visible.if + ? api_fragment(0, [api_static_fragment($fragment1(), 2)], 0) + : $cmp.visible.elseif + ? api_fragment(0, [api_static_fragment($fragment2(), 4)], 0) + : $cmp.visible.elseif2 + ? api_fragment( + 0, + [api_dynamic_component("x-foo", $cmp.trackedProp.foo, stc0)], + 0 + ) + : api_fragment(0, [api_static_fragment($fragment3(), 7)], 0), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif-multiple/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/actual.html new file mode 100644 index 0000000000..c55738e583 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/actual.html @@ -0,0 +1,8 @@ + diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/ast.json new file mode 100644 index 0000000000..033b6e1815 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/ast.json @@ -0,0 +1,280 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 8, + "endColumn": 12, + "start": 0, + "end": 216, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 8, + "startColumn": 1, + "endLine": 8, + "endColumn": 12, + "start": 205, + "end": 216 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 11, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 9, + "end": 11, + "name": "if" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 34, + "start": 25, + "end": 44 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 4, + "endColumn": 16, + "start": 15, + "end": 91 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 34, + "start": 25, + "end": 44 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 30, + "start": 54, + "end": 75, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 13, + "start": 54, + "end": 58 + }, + "endTag": { + "startLine": 3, + "startColumn": 25, + "endLine": 3, + "endColumn": 30, + "start": 70, + "end": 75 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "if condition", + "value": { + "type": "Literal", + "value": "if condition" + }, + "location": { + "startLine": 3, + "startColumn": 13, + "endLine": 3, + "endColumn": 25, + "start": 58, + "end": 70 + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 15, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 9, + "end": 15, + "name": "elseif" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 42, + "start": 106, + "end": 133 + } + }, + "location": { + "startLine": 5, + "startColumn": 5, + "endLine": 7, + "endColumn": 16, + "start": 96, + "end": 204 + }, + "directiveLocation": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 42, + "start": 106, + "end": 133 + }, + "children": [ + { + "type": "Component", + "name": "x-foo", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 54, + "start": 143, + "end": 188, + "startTag": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 46, + "start": 143, + "end": 180 + }, + "endTag": { + "startLine": 6, + "startColumn": 46, + "endLine": 6, + "endColumn": 54, + "start": 180, + "end": 188 + } + }, + "attributes": [], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "Dynamic", + "value": { + "type": "MemberExpression", + "start": 1, + "end": 16, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 12, + "name": "trackedProp" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 13, + "end": 16, + "name": "foo" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 6, + "startColumn": 16, + "endLine": 6, + "endColumn": 45, + "start": 150, + "end": 179 + } + }, + "location": { + "startLine": 6, + "startColumn": 16, + "endLine": 6, + "endColumn": 45, + "start": 150, + "end": 179 + } + } + ], + "listeners": [], + "children": [] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/config.json new file mode 100644 index 0000000000..7fa4e84f22 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/config.json @@ -0,0 +1,3 @@ +{ + "experimentalDynamicDirective": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/expected.js new file mode 100644 index 0000000000..7a836a714b --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/expected.js @@ -0,0 +1,26 @@ +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment`if condition`; +const stc0 = { + key: 3, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { + st: api_static_fragment, + fr: api_fragment, + dc: api_dynamic_component, + } = $api; + return [ + $cmp.visible.if + ? api_fragment(0, [api_static_fragment($fragment1(), 2)], 0) + : $cmp.visible.elseif + ? api_fragment( + 0, + [api_dynamic_component("x-foo", $cmp.trackedProp.foo, stc0)], + 0 + ) + : null, + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if-elseif/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/actual.html new file mode 100644 index 0000000000..761702d104 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/actual.html @@ -0,0 +1,5 @@ + diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/ast.json new file mode 100644 index 0000000000..9f08e37b1d --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/ast.json @@ -0,0 +1,172 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 0, + "end": 127, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 5, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 116, + "end": 127 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "MemberExpression", + "start": 1, + "end": 11, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 9, + "end": 11, + "name": "if" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 34, + "start": 25, + "end": 44 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 4, + "endColumn": 16, + "start": 15, + "end": 115 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 34, + "start": 25, + "end": 44 + }, + "children": [ + { + "type": "Component", + "name": "x-foo", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 54, + "start": 54, + "end": 99, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 46, + "start": 54, + "end": 91 + }, + "endTag": { + "startLine": 3, + "startColumn": 46, + "endLine": 3, + "endColumn": 54, + "start": 91, + "end": 99 + } + }, + "attributes": [], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "Dynamic", + "value": { + "type": "MemberExpression", + "start": 1, + "end": 16, + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$cmp" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 12, + "name": "trackedProp" + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 13, + "end": 16, + "name": "foo" + }, + "computed": false, + "optional": false, + "location": { + "startLine": 3, + "startColumn": 16, + "endLine": 3, + "endColumn": 45, + "start": 61, + "end": 90 + } + }, + "location": { + "startLine": 3, + "startColumn": 16, + "endLine": 3, + "endColumn": 45, + "start": 61, + "end": 90 + } + } + ], + "listeners": [], + "children": [] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/config.json new file mode 100644 index 0000000000..7fa4e84f22 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/config.json @@ -0,0 +1,3 @@ +{ + "experimentalDynamicDirective": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/expected.js new file mode 100644 index 0000000000..80d1b73935 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/expected.js @@ -0,0 +1,19 @@ +import { registerTemplate } from "lwc"; +const stc0 = { + key: 1, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { dc: api_dynamic_component, fr: api_fragment } = $api; + return [ + $cmp.visible.if + ? api_fragment( + 0, + [api_dynamic_component("x-foo", $cmp.trackedProp.foo, stc0)], + 0 + ) + : null, + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/dynamic/if/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-expression/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-expression/actual.html new file mode 100644 index 0000000000..a841b54b0e --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-expression/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-expression/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-expression/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-expression/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-expression/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-expression/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-expression/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-expression/metadata.json new file mode 100644 index 0000000000..75d50952e0 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-expression/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1161, + "message": "LWC1161: lwc:else directive cannot have a value", + "level": 1, + "location": { + "line": 3, + "column": 5, + "start": 74, + "length": 61 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/cannot-be-preceeded-by-text-node/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/cannot-be-preceeded-by-text-node/actual.html new file mode 100644 index 0000000000..d8baa61e30 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/cannot-be-preceeded-by-text-node/actual.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/cannot-be-preceeded-by-text-node/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/cannot-be-preceeded-by-text-node/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/cannot-be-preceeded-by-text-node/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/cannot-be-preceeded-by-text-node/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/cannot-be-preceeded-by-text-node/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/cannot-be-preceeded-by-text-node/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/cannot-be-preceeded-by-text-node/metadata.json new file mode 100644 index 0000000000..c7214a199f --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/cannot-be-preceeded-by-text-node/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1165, + "message": "LWC1165: 'lwc:elseif' directive must be used immediately after an element with 'lwc:if' or 'lwc:elseif'. No such element found.", + "level": 1, + "location": { + "line": 4, + "column": 5, + "start": 77, + "length": 48 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/must-be-preceeded-by-if-or-elseif/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/must-be-preceeded-by-if-or-elseif/actual.html new file mode 100644 index 0000000000..d7790d99cb --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/must-be-preceeded-by-if-or-elseif/actual.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/must-be-preceeded-by-if-or-elseif/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/must-be-preceeded-by-if-or-elseif/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/must-be-preceeded-by-if-or-elseif/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/must-be-preceeded-by-if-or-elseif/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/must-be-preceeded-by-if-or-elseif/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/must-be-preceeded-by-if-or-elseif/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/must-be-preceeded-by-if-or-elseif/metadata.json new file mode 100644 index 0000000000..c7214a199f --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else-if/must-be-preceeded-by-if-or-elseif/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1165, + "message": "LWC1165: 'lwc:elseif' directive must be used immediately after an element with 'lwc:if' or 'lwc:elseif'. No such element found.", + "level": 1, + "location": { + "line": 4, + "column": 5, + "start": 77, + "length": 48 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/cannot-be-preceeded-by-text-node/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/cannot-be-preceeded-by-text-node/actual.html new file mode 100644 index 0000000000..77f58374e3 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/cannot-be-preceeded-by-text-node/actual.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/cannot-be-preceeded-by-text-node/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/cannot-be-preceeded-by-text-node/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/cannot-be-preceeded-by-text-node/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/cannot-be-preceeded-by-text-node/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/cannot-be-preceeded-by-text-node/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/cannot-be-preceeded-by-text-node/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/cannot-be-preceeded-by-text-node/metadata.json new file mode 100644 index 0000000000..2881eb52d0 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/cannot-be-preceeded-by-text-node/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1165, + "message": "LWC1165: 'lwc:else' directive must be used immediately after an element with 'lwc:if' or 'lwc:elseif'. No such element found.", + "level": 1, + "location": { + "line": 4, + "column": 5, + "start": 77, + "length": 35 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/must-be-preceeded-by-if-or-elseif/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/must-be-preceeded-by-if-or-elseif/actual.html new file mode 100644 index 0000000000..cd87ceb46d --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/must-be-preceeded-by-if-or-elseif/actual.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/must-be-preceeded-by-if-or-elseif/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/must-be-preceeded-by-if-or-elseif/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/must-be-preceeded-by-if-or-elseif/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/must-be-preceeded-by-if-or-elseif/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/must-be-preceeded-by-if-or-elseif/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/must-be-preceeded-by-if-or-elseif/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/must-be-preceeded-by-if-or-elseif/metadata.json new file mode 100644 index 0000000000..2881eb52d0 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-sibling/else/must-be-preceeded-by-if-or-elseif/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1165, + "message": "LWC1165: 'lwc:else' directive must be used immediately after an element with 'lwc:if' or 'lwc:elseif'. No such element found.", + "level": 1, + "location": { + "line": 4, + "column": 5, + "start": 77, + "length": 35 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-string-value/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-string-value/actual.html new file mode 100644 index 0000000000..c3067ff388 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-string-value/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-string-value/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-string-value/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-string-value/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-string-value/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-string-value/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-string-value/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-string-value/metadata.json new file mode 100644 index 0000000000..917d9c1a12 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-invalid-string-value/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1161, + "message": "LWC1161: lwc:else directive cannot have a value", + "level": 1, + "location": { + "line": 3, + "column": 5, + "start": 74, + "length": 52 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/elseif-else/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/elseif-else/actual.html new file mode 100644 index 0000000000..5532ab5212 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/elseif-else/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/elseif-else/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/elseif-else/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/elseif-else/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/elseif-else/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/elseif-else/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/elseif-else/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/elseif-else/metadata.json new file mode 100644 index 0000000000..14ca8b7858 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/elseif-else/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1163, + "message": "LWC1163: Invalid usage of 'lwc:elseif' and 'lwc:else' directives on the same element.", + "level": 1, + "location": { + "line": 3, + "column": 5, + "start": 58, + "length": 67 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-else/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-else/actual.html new file mode 100644 index 0000000000..018bd16dab --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-else/actual.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-else/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-else/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-else/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-else/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-else/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-else/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-else/metadata.json new file mode 100644 index 0000000000..770be82ba9 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-else/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1162, + "message": "LWC1162: Invalid usage of 'lwc:if' and 'lwc:else' directives on the same element.", + "level": 1, + "location": { + "line": 2, + "column": 5, + "start": 15, + "length": 63 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-elseif/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-elseif/actual.html new file mode 100644 index 0000000000..a8db9f820c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-elseif/actual.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-elseif/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-elseif/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-elseif/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-elseif/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-elseif/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-elseif/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-elseif/metadata.json new file mode 100644 index 0000000000..c351d99ab2 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/error-multiple-directives/if-elseif/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1162, + "message": "LWC1162: Invalid usage of 'lwc:if' and 'lwc:elseif' directives on the same element.", + "level": 1, + "location": { + "line": 2, + "column": 5, + "start": 15, + "length": 74 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/actual.html new file mode 100644 index 0000000000..20bdd01ded --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/ast.json new file mode 100644 index 0000000000..3473cb0eab --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/ast.json @@ -0,0 +1,156 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 0, + "end": 108, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 4, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 97, + "end": 108 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 43, + "start": 15, + "end": 53 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Component", + "name": "c-custom", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 43, + "start": 15, + "end": 53, + "startTag": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 32, + "start": 15, + "end": 42 + }, + "endTag": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 43, + "start": 42, + "end": 53 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 43, + "start": 58, + "end": 96 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 19, + "endLine": 3, + "endColumn": 27, + "start": 72, + "end": 80 + }, + "children": [ + { + "type": "Component", + "name": "c-custom-alt", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 43, + "start": 58, + "end": 96, + "startTag": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 28, + "start": 58, + "end": 81 + }, + "endTag": { + "startLine": 3, + "startColumn": 28, + "endLine": 3, + "endColumn": 43, + "start": 81, + "end": 96 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/expected.js new file mode 100644 index 0000000000..db6e215850 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/expected.js @@ -0,0 +1,24 @@ +import _cCustom from "c/custom"; +import _cCustomAlt from "c/customAlt"; +import { registerTemplate } from "lwc"; +const stc0 = { + key: 1, +}; +const stc1 = { + key: 2, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { c: api_custom_element, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_custom_element("c-custom", _cCustom, stc0)], 0) + : api_fragment( + 0, + [api_custom_element("c-custom-alt", _cCustomAlt, stc1)], + 0 + ), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/components/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/actual.html new file mode 100644 index 0000000000..0785fefedd --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/ast.json new file mode 100644 index 0000000000..130c56ea1b --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/ast.json @@ -0,0 +1,190 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 0, + "end": 108, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 4, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 97, + "end": 108 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 9, + "endLine": 2, + "endColumn": 25, + "start": 19, + "end": 35 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 45, + "start": 15, + "end": 55 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 9, + "endLine": 2, + "endColumn": 25, + "start": 19, + "end": 35 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 45, + "start": 15, + "end": 55, + "startTag": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 26, + "start": 15, + "end": 36 + }, + "endTag": { + "startLine": 2, + "startColumn": 40, + "endLine": 2, + "endColumn": 45, + "start": 50, + "end": 55 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Visible Header", + "value": { + "type": "Literal", + "value": "Visible Header" + }, + "location": { + "startLine": 2, + "startColumn": 26, + "endLine": 2, + "endColumn": 40, + "start": 36, + "end": 50 + } + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 41, + "start": 60, + "end": 96 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 17, + "start": 64, + "end": 72 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 41, + "start": 60, + "end": 96, + "startTag": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 18, + "start": 60, + "end": 73 + }, + "endTag": { + "startLine": 3, + "startColumn": 36, + "endLine": 3, + "endColumn": 41, + "start": 91, + "end": 96 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Alternative Header", + "value": { + "type": "Literal", + "value": "Alternative Header" + }, + "location": { + "startLine": 3, + "startColumn": 18, + "endLine": 3, + "endColumn": 36, + "start": 73, + "end": 91 + } + } + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/expected.js new file mode 100644 index 0000000000..857cece0b6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/expected.js @@ -0,0 +1,14 @@ +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment`Visible Header`; +const $fragment2 = parseFragment`Alternative Header`; +function tmpl($api, $cmp, $slotset, $ctx) { + const { st: api_static_fragment, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_static_fragment($fragment1(), 2)], 0) + : api_fragment(0, [api_static_fragment($fragment2(), 4)], 0), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/html-elements/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/actual.html new file mode 100644 index 0000000000..5a15098e30 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/ast.json new file mode 100644 index 0000000000..a321123021 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/ast.json @@ -0,0 +1,120 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 0, + "end": 121, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 4, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 110, + "end": 121 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 59, + "start": 15, + "end": 69 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Text", + "raw": "Conditional Text", + "value": { + "type": "Literal", + "value": "Conditional Text" + }, + "location": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 48, + "start": 42, + "end": 58 + } + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 40, + "start": 74, + "end": 109 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 23, + "start": 84, + "end": 92 + }, + "children": [ + { + "type": "Text", + "raw": "Else!", + "value": { + "type": "Literal", + "value": "Else!" + }, + "location": { + "startLine": 3, + "startColumn": 24, + "endLine": 3, + "endColumn": 29, + "start": 93, + "end": 98 + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/expected.js new file mode 100644 index 0000000000..2be1cdb2ee --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/expected.js @@ -0,0 +1,12 @@ +import { registerTemplate } from "lwc"; +function tmpl($api, $cmp, $slotset, $ctx) { + const { t: api_text, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_text("Conditional Text")], 0) + : api_fragment(0, [api_text("Else!")], 0), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-else/template/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/actual.html new file mode 100644 index 0000000000..23a7d137d3 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/actual.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/ast.json new file mode 100644 index 0000000000..7b1b95f345 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/ast.json @@ -0,0 +1,225 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 0, + "end": 170, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 5, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 159, + "end": 170 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 43, + "start": 15, + "end": 53 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Component", + "name": "c-custom", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 43, + "start": 15, + "end": 53, + "startTag": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 32, + "start": 15, + "end": 42 + }, + "endTag": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 43, + "start": 42, + "end": 53 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 7, + "name": "elseif", + "location": { + "startLine": 3, + "startColumn": 22, + "endLine": 3, + "endColumn": 41, + "start": 75, + "end": 94 + } + }, + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 60, + "start": 58, + "end": 113 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 22, + "endLine": 3, + "endColumn": 41, + "start": 75, + "end": 94 + }, + "children": [ + { + "type": "Component", + "name": "c-custom-elseif", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 60, + "start": 58, + "end": 113, + "startTag": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 42, + "start": 58, + "end": 95 + }, + "endTag": { + "startLine": 3, + "startColumn": 42, + "endLine": 3, + "endColumn": 60, + "start": 95, + "end": 113 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 4, + "startColumn": 5, + "endLine": 4, + "endColumn": 45, + "start": 118, + "end": 158 + }, + "directiveLocation": { + "startLine": 4, + "startColumn": 20, + "endLine": 4, + "endColumn": 28, + "start": 133, + "end": 141 + }, + "children": [ + { + "type": "Component", + "name": "c-custom-else", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 4, + "startColumn": 5, + "endLine": 4, + "endColumn": 45, + "start": 118, + "end": 158, + "startTag": { + "startLine": 4, + "startColumn": 5, + "endLine": 4, + "endColumn": 29, + "start": 118, + "end": 142 + }, + "endTag": { + "startLine": 4, + "startColumn": 29, + "endLine": 4, + "endColumn": 45, + "start": 142, + "end": 158 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/expected.js new file mode 100644 index 0000000000..0d98ae9256 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/expected.js @@ -0,0 +1,34 @@ +import _cCustom from "c/custom"; +import _cCustomElseif from "c/customElseif"; +import _cCustomElse from "c/customElse"; +import { registerTemplate } from "lwc"; +const stc0 = { + key: 1, +}; +const stc1 = { + key: 2, +}; +const stc2 = { + key: 3, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { c: api_custom_element, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_custom_element("c-custom", _cCustom, stc0)], 0) + : $cmp.elseif + ? api_fragment( + 0, + [api_custom_element("c-custom-elseif", _cCustomElseif, stc1)], + 0 + ) + : api_fragment( + 0, + [api_custom_element("c-custom-else", _cCustomElse, stc2)], + 0 + ), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/components/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/actual.html new file mode 100644 index 0000000000..599bb00658 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/actual.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/ast.json new file mode 100644 index 0000000000..abbe494253 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/ast.json @@ -0,0 +1,276 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 0, + "end": 175, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 5, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 164, + "end": 175 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 9, + "endLine": 2, + "endColumn": 25, + "start": 19, + "end": 35 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 45, + "start": 15, + "end": 55 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 9, + "endLine": 2, + "endColumn": 25, + "start": 19, + "end": 35 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 45, + "start": 15, + "end": 55, + "startTag": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 26, + "start": 15, + "end": 36 + }, + "endTag": { + "startLine": 2, + "startColumn": 40, + "endLine": 2, + "endColumn": 45, + "start": 50, + "end": 55 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Visible Header", + "value": { + "type": "Literal", + "value": "Visible Header" + }, + "location": { + "startLine": 2, + "startColumn": 26, + "endLine": 2, + "endColumn": 40, + "start": 36, + "end": 50 + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 16, + "name": "elseifCondition", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 37, + "start": 64, + "end": 92 + } + }, + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 67, + "start": 60, + "end": 122 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 37, + "start": 64, + "end": 92 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 67, + "start": 60, + "end": 122, + "startTag": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 38, + "start": 60, + "end": 93 + }, + "endTag": { + "startLine": 3, + "startColumn": 62, + "endLine": 3, + "endColumn": 67, + "start": 117, + "end": 122 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "First Alternative Header", + "value": { + "type": "Literal", + "value": "First Alternative Header" + }, + "location": { + "startLine": 3, + "startColumn": 38, + "endLine": 3, + "endColumn": 62, + "start": 93, + "end": 117 + } + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 4, + "startColumn": 5, + "endLine": 4, + "endColumn": 41, + "start": 127, + "end": 163 + }, + "directiveLocation": { + "startLine": 4, + "startColumn": 9, + "endLine": 4, + "endColumn": 17, + "start": 131, + "end": 139 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 4, + "startColumn": 5, + "endLine": 4, + "endColumn": 41, + "start": 127, + "end": 163, + "startTag": { + "startLine": 4, + "startColumn": 5, + "endLine": 4, + "endColumn": 18, + "start": 127, + "end": 140 + }, + "endTag": { + "startLine": 4, + "startColumn": 36, + "endLine": 4, + "endColumn": 41, + "start": 158, + "end": 163 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Alternative Header", + "value": { + "type": "Literal", + "value": "Alternative Header" + }, + "location": { + "startLine": 4, + "startColumn": 18, + "endLine": 4, + "endColumn": 36, + "start": 140, + "end": 158 + } + } + ] + } + ] + } + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/expected.js new file mode 100644 index 0000000000..5d514421fb --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/expected.js @@ -0,0 +1,17 @@ +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment`Visible Header`; +const $fragment2 = parseFragment`First Alternative Header`; +const $fragment3 = parseFragment`Alternative Header`; +function tmpl($api, $cmp, $slotset, $ctx) { + const { st: api_static_fragment, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_static_fragment($fragment1(), 2)], 0) + : $cmp.elseifCondition + ? api_fragment(0, [api_static_fragment($fragment2(), 4)], 0) + : api_fragment(0, [api_static_fragment($fragment3(), 6)], 0), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/html-elements/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/actual.html new file mode 100644 index 0000000000..954d7814a6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/actual.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/ast.json new file mode 100644 index 0000000000..08744352c2 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/ast.json @@ -0,0 +1,171 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 0, + "end": 183, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 5, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 172, + "end": 183 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 59, + "start": 15, + "end": 69 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Text", + "raw": "Conditional Text", + "value": { + "type": "Literal", + "value": "Conditional Text" + }, + "location": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 48, + "start": 42, + "end": 58 + } + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 16, + "name": "elseifCondition", + "location": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 43, + "start": 84, + "end": 112 + } + }, + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 62, + "start": 74, + "end": 131 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 43, + "start": 84, + "end": 112 + }, + "children": [ + { + "type": "Text", + "raw": "Elseif!", + "value": { + "type": "Literal", + "value": "Elseif!" + }, + "location": { + "startLine": 3, + "startColumn": 44, + "endLine": 3, + "endColumn": 51, + "start": 113, + "end": 120 + } + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 4, + "startColumn": 5, + "endLine": 4, + "endColumn": 40, + "start": 136, + "end": 171 + }, + "directiveLocation": { + "startLine": 4, + "startColumn": 15, + "endLine": 4, + "endColumn": 23, + "start": 146, + "end": 154 + }, + "children": [ + { + "type": "Text", + "raw": "Else!", + "value": { + "type": "Literal", + "value": "Else!" + }, + "location": { + "startLine": 4, + "startColumn": 24, + "endLine": 4, + "endColumn": 29, + "start": 155, + "end": 160 + } + } + ] + } + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/expected.js new file mode 100644 index 0000000000..17662b347b --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/expected.js @@ -0,0 +1,14 @@ +import { registerTemplate } from "lwc"; +function tmpl($api, $cmp, $slotset, $ctx) { + const { t: api_text, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_text("Conditional Text")], 0) + : $cmp.elseifCondition + ? api_fragment(0, [api_text("Elseif!")], 0) + : api_fragment(0, [api_text("Else!")], 0), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif-else/template/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/actual.html new file mode 100644 index 0000000000..e2fadf6925 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/ast.json new file mode 100644 index 0000000000..22cc0fff54 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/ast.json @@ -0,0 +1,204 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 0, + "end": 158, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 4, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 147, + "end": 158 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 57, + "start": 15, + "end": 67 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Component", + "name": "c-custom", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 57, + "start": 15, + "end": 67, + "startTag": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 32, + "start": 15, + "end": 42 + }, + "endTag": { + "startLine": 2, + "startColumn": 46, + "endLine": 2, + "endColumn": 57, + "start": 56, + "end": 67 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Visible Header", + "value": { + "type": "Literal", + "value": "Visible Header" + }, + "location": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 46, + "start": 42, + "end": 56 + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 16, + "name": "elseifCondition", + "location": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 43, + "start": 82, + "end": 110 + } + }, + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 79, + "start": 72, + "end": 146 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 43, + "start": 82, + "end": 110 + }, + "children": [ + { + "type": "Component", + "name": "c-custom", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 79, + "start": 72, + "end": 146, + "startTag": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 44, + "start": 72, + "end": 111 + }, + "endTag": { + "startLine": 3, + "startColumn": 68, + "endLine": 3, + "endColumn": 79, + "start": 135, + "end": 146 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "First Alternative Header", + "value": { + "type": "Literal", + "value": "First Alternative Header" + }, + "location": { + "startLine": 3, + "startColumn": 44, + "endLine": 3, + "endColumn": 68, + "start": 111, + "end": 135 + } + } + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/expected.js new file mode 100644 index 0000000000..1ffb4be08e --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/expected.js @@ -0,0 +1,37 @@ +import _cCustom from "c/custom"; +import { registerTemplate } from "lwc"; +const stc0 = { + key: 1, +}; +const stc1 = { + key: 2, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { t: api_text, c: api_custom_element, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment( + 0, + [ + api_custom_element("c-custom", _cCustom, stc0, [ + api_text("Visible Header"), + ]), + ], + 0 + ) + : $cmp.elseifCondition + ? api_fragment( + 0, + [ + api_custom_element("c-custom", _cCustom, stc1, [ + api_text("First Alternative Header"), + ]), + ], + 0 + ) + : null, + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/components/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/actual.html new file mode 100644 index 0000000000..4da4d5a9b9 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/ast.json new file mode 100644 index 0000000000..d5631d5922 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/ast.json @@ -0,0 +1,204 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 0, + "end": 134, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 4, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 123, + "end": 134 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 9, + "endLine": 2, + "endColumn": 25, + "start": 19, + "end": 35 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 45, + "start": 15, + "end": 55 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 9, + "endLine": 2, + "endColumn": 25, + "start": 19, + "end": 35 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 45, + "start": 15, + "end": 55, + "startTag": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 26, + "start": 15, + "end": 36 + }, + "endTag": { + "startLine": 2, + "startColumn": 40, + "endLine": 2, + "endColumn": 45, + "start": 50, + "end": 55 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Visible Header", + "value": { + "type": "Literal", + "value": "Visible Header" + }, + "location": { + "startLine": 2, + "startColumn": 26, + "endLine": 2, + "endColumn": 40, + "start": 36, + "end": 50 + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 16, + "name": "elseifCondition", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 37, + "start": 64, + "end": 92 + } + }, + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 67, + "start": 60, + "end": 122 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 37, + "start": 64, + "end": 92 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 67, + "start": 60, + "end": 122, + "startTag": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 38, + "start": 60, + "end": 93 + }, + "endTag": { + "startLine": 3, + "startColumn": 62, + "endLine": 3, + "endColumn": 67, + "start": 117, + "end": 122 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "First Alternative Header", + "value": { + "type": "Literal", + "value": "First Alternative Header" + }, + "location": { + "startLine": 3, + "startColumn": 38, + "endLine": 3, + "endColumn": 62, + "start": 93, + "end": 117 + } + } + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/expected.js new file mode 100644 index 0000000000..b2fd3f09eb --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/expected.js @@ -0,0 +1,16 @@ +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment`Visible Header`; +const $fragment2 = parseFragment`First Alternative Header`; +function tmpl($api, $cmp, $slotset, $ctx) { + const { st: api_static_fragment, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_static_fragment($fragment1(), 2)], 0) + : $cmp.elseifCondition + ? api_fragment(0, [api_static_fragment($fragment2(), 4)], 0) + : null, + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/html-elements/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/actual.html new file mode 100644 index 0000000000..bf66fe9cda --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/ast.json new file mode 100644 index 0000000000..9275928b9a --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/ast.json @@ -0,0 +1,134 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 0, + "end": 138, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 4, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 127, + "end": 138 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 59, + "start": 15, + "end": 69 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Text", + "raw": "Conditional Text", + "value": { + "type": "Literal", + "value": "Conditional Text" + }, + "location": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 48, + "start": 42, + "end": 58 + } + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 11, + "name": "displayAlt", + "location": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 38, + "start": 84, + "end": 107 + } + }, + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 57, + "start": 74, + "end": 126 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 38, + "start": 84, + "end": 107 + }, + "children": [ + { + "type": "Text", + "raw": "Elseif!", + "value": { + "type": "Literal", + "value": "Elseif!" + }, + "location": { + "startLine": 3, + "startColumn": 39, + "endLine": 3, + "endColumn": 46, + "start": 108, + "end": 115 + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/expected.js new file mode 100644 index 0000000000..fd41f91074 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/expected.js @@ -0,0 +1,14 @@ +import { registerTemplate } from "lwc"; +function tmpl($api, $cmp, $slotset, $ctx) { + const { t: api_text, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_text("Conditional Text")], 0) + : $cmp.displayAlt + ? api_fragment(0, [api_text("Elseif!")], 0) + : null, + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-elseif/template/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/actual.html new file mode 100644 index 0000000000..68fd7d77c7 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/actual.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/ast.json new file mode 100644 index 0000000000..bc0e35b440 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/ast.json @@ -0,0 +1,101 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 3, + "endColumn": 12, + "start": 0, + "end": 65, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 3, + "startColumn": 1, + "endLine": 3, + "endColumn": 12, + "start": 54, + "end": 65 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 43, + "start": 15, + "end": 53 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Component", + "name": "c-custom", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 43, + "start": 15, + "end": 53, + "startTag": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 32, + "start": 15, + "end": 42 + }, + "endTag": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 43, + "start": 42, + "end": 53 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/expected.js new file mode 100644 index 0000000000..6aeff73c86 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/expected.js @@ -0,0 +1,16 @@ +import _cCustom from "c/custom"; +import { registerTemplate } from "lwc"; +const stc0 = { + key: 1, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { c: api_custom_element, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_custom_element("c-custom", _cCustom, stc0)], 0) + : null, + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/components/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/actual.html new file mode 100644 index 0000000000..fcc808dff5 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/actual.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/ast.json new file mode 100644 index 0000000000..82b372eec4 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/ast.json @@ -0,0 +1,101 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 3, + "endColumn": 12, + "start": 0, + "end": 53, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 3, + "startColumn": 1, + "endLine": 3, + "endColumn": 12, + "start": 42, + "end": 53 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 9, + "endLine": 2, + "endColumn": 25, + "start": 19, + "end": 35 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 31, + "start": 15, + "end": 41 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 9, + "endLine": 2, + "endColumn": 25, + "start": 19, + "end": 35 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 31, + "start": 15, + "end": 41, + "startTag": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 26, + "start": 15, + "end": 36 + }, + "endTag": { + "startLine": 2, + "startColumn": 26, + "endLine": 2, + "endColumn": 31, + "start": 36, + "end": 41 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/expected.js new file mode 100644 index 0000000000..c3f17917c1 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/expected.js @@ -0,0 +1,13 @@ +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment``; +function tmpl($api, $cmp, $slotset, $ctx) { + const { st: api_static_fragment, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_static_fragment($fragment1(), 2)], 0) + : null, + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/html-elements/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/actual.html new file mode 100644 index 0000000000..3a0b07a4c4 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/actual.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/ast.json new file mode 100644 index 0000000000..3bac6918e3 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/ast.json @@ -0,0 +1,83 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 3, + "endColumn": 12, + "start": 0, + "end": 81, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 3, + "startColumn": 1, + "endLine": 3, + "endColumn": 12, + "start": 70, + "end": 81 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 59, + "start": 15, + "end": 69 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Text", + "raw": "Conditional Text", + "value": { + "type": "Literal", + "value": "Conditional Text" + }, + "location": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 48, + "start": 42, + "end": 58 + } + } + ] + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/expected.js new file mode 100644 index 0000000000..773006ae00 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/expected.js @@ -0,0 +1,10 @@ +import { registerTemplate } from "lwc"; +function tmpl($api, $cmp, $slotset, $ctx) { + const { t: api_text, fr: api_fragment } = $api; + return [ + $cmp.visible ? api_fragment(0, [api_text("Conditional Text")], 0) : null, + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/if-only/template/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/actual.html new file mode 100644 index 0000000000..07b85d7695 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/ast.json new file mode 100644 index 0000000000..ca9a0548b6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/ast.json @@ -0,0 +1,214 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 0, + "end": 204, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 4, + "startColumn": 1, + "endLine": 4, + "endColumn": 12, + "start": 193, + "end": 204 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 48, + "endLine": 2, + "endColumn": 64, + "start": 58, + "end": 74 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 97, + "start": 15, + "end": 107 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 48, + "endLine": 2, + "endColumn": 64, + "start": 58, + "end": 74 + }, + "children": [ + { + "type": "ForEach", + "expression": { + "type": "Identifier", + "start": 1, + "end": 6, + "name": "items", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "item": { + "type": "Identifier", + "name": "item", + "location": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 47, + "start": 42, + "end": 57 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 97, + "start": 15, + "end": 107 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Text", + "raw": "Conditional Iteration", + "value": { + "type": "Literal", + "value": "Conditional Iteration" + }, + "location": { + "startLine": 2, + "startColumn": 65, + "endLine": 2, + "endColumn": 86, + "start": 75, + "end": 96 + } + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 85, + "start": 112, + "end": 192 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 51, + "endLine": 3, + "endColumn": 59, + "start": 158, + "end": 166 + }, + "children": [ + { + "type": "ForEach", + "expression": { + "type": "Identifier", + "start": 1, + "end": 9, + "name": "altItems", + "location": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 34, + "start": 122, + "end": 141 + } + }, + "item": { + "type": "Identifier", + "name": "item", + "location": { + "startLine": 3, + "startColumn": 35, + "endLine": 3, + "endColumn": 50, + "start": 142, + "end": 157 + } + }, + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 85, + "start": 112, + "end": 192 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 34, + "start": 122, + "end": 141 + }, + "children": [ + { + "type": "Text", + "raw": "Else Iteration", + "value": { + "type": "Literal", + "value": "Else Iteration" + }, + "location": { + "startLine": 3, + "startColumn": 60, + "endLine": 3, + "endColumn": 74, + "start": 167, + "end": 181 + } + } + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/expected.js new file mode 100644 index 0000000000..f85b6be89d --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/expected.js @@ -0,0 +1,24 @@ +import { registerTemplate } from "lwc"; +function tmpl($api, $cmp, $slotset, $ctx) { + const { t: api_text, i: api_iterator, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment( + 0, + api_iterator($cmp.items, function (item) { + return api_text("Conditional Iteration"); + }), + 0 + ) + : api_fragment( + 0, + api_iterator($cmp.altItems, function (item) { + return api_text("Else Iteration"); + }), + 0 + ), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/foreach-if/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-else/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-else/actual.html new file mode 100644 index 0000000000..8b39f1cde0 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-else/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-else/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-else/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-else/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-else/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-else/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-else/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-else/metadata.json new file mode 100644 index 0000000000..c8c8d583f7 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-else/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1165, + "message": "LWC1165: 'lwc:else' directive must be used immediately after an element with 'lwc:if' or 'lwc:elseif'. No such element found.", + "level": 1, + "location": { + "line": 3, + "column": 5, + "start": 62, + "length": 35 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-elseif/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-elseif/actual.html new file mode 100644 index 0000000000..c518b54fa4 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-elseif/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-elseif/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-elseif/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-elseif/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-elseif/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-elseif/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-elseif/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-elseif/metadata.json new file mode 100644 index 0000000000..45a74f0676 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/if-true-elseif/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1165, + "message": "LWC1165: 'lwc:elseif' directive must be used immediately after an element with 'lwc:if' or 'lwc:elseif'. No such element found.", + "level": 1, + "location": { + "line": 3, + "column": 5, + "start": 62, + "length": 55 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-else/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-else/actual.html new file mode 100644 index 0000000000..3dc4fe4822 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-else/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-else/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-else/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-else/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-else/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-else/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-else/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-else/metadata.json new file mode 100644 index 0000000000..83e5dca5e3 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-else/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1166, + "message": "LWC1166: 'if:true' directive cannot be used with 'lwc:if', 'lwc:elseif', or 'lwc:else directives on the same element.", + "level": 1, + "location": { + "line": 3, + "column": 5, + "start": 74, + "length": 64 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-elseif/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-elseif/actual.html new file mode 100644 index 0000000000..a43bf156aa --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-elseif/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-elseif/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-elseif/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-elseif/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-elseif/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-elseif/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-elseif/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-elseif/metadata.json new file mode 100644 index 0000000000..126a259441 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/interop/mixed-if-true-elseif/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1166, + "message": "LWC1166: 'if:true' directive cannot be used with 'lwc:if', 'lwc:elseif', or 'lwc:else directives on the same element.", + "level": 1, + "location": { + "line": 3, + "column": 5, + "start": 74, + "length": 70 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/actual.html new file mode 100644 index 0000000000..29ecab7278 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/actual.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/ast.json new file mode 100644 index 0000000000..3c98e0bef7 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/ast.json @@ -0,0 +1,241 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 0, + "end": 175, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 5, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 164, + "end": 175 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 59, + "start": 15, + "end": 69 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Text", + "raw": "Conditional Text", + "value": { + "type": "Literal", + "value": "Conditional Text" + }, + "location": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 48, + "start": 42, + "end": 58 + } + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 16, + "name": "elseifCondition", + "location": { + "startLine": 3, + "startColumn": 10, + "endLine": 3, + "endColumn": 38, + "start": 79, + "end": 107 + } + }, + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 52, + "start": 74, + "end": 121 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 10, + "endLine": 3, + "endColumn": 38, + "start": 79, + "end": 107 + }, + "children": [ + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 52, + "start": 74, + "end": 121, + "startTag": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 39, + "start": 74, + "end": 108 + }, + "endTag": { + "startLine": 3, + "startColumn": 46, + "endLine": 3, + "endColumn": 52, + "start": 115, + "end": 121 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Elseif!", + "value": { + "type": "Literal", + "value": "Elseif!" + }, + "location": { + "startLine": 3, + "startColumn": 39, + "endLine": 3, + "endColumn": 46, + "start": 108, + "end": 115 + } + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 4, + "startColumn": 5, + "endLine": 4, + "endColumn": 42, + "start": 126, + "end": 163 + }, + "directiveLocation": { + "startLine": 4, + "startColumn": 16, + "endLine": 4, + "endColumn": 24, + "start": 137, + "end": 145 + }, + "children": [ + { + "type": "Component", + "name": "c-default", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 4, + "startColumn": 5, + "endLine": 4, + "endColumn": 42, + "start": 126, + "end": 163, + "startTag": { + "startLine": 4, + "startColumn": 5, + "endLine": 4, + "endColumn": 25, + "start": 126, + "end": 146 + }, + "endTag": { + "startLine": 4, + "startColumn": 30, + "endLine": 4, + "endColumn": 42, + "start": 151, + "end": 163 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Else!", + "value": { + "type": "Literal", + "value": "Else!" + }, + "location": { + "startLine": 4, + "startColumn": 25, + "endLine": 4, + "endColumn": 30, + "start": 146, + "end": 151 + } + } + ] + } + ] + } + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/expected.js new file mode 100644 index 0000000000..7721e8bf75 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/expected.js @@ -0,0 +1,32 @@ +import _cDefault from "c/default"; +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment`Elseif!`; +const stc0 = { + key: 3, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { + t: api_text, + fr: api_fragment, + st: api_static_fragment, + c: api_custom_element, + } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_text("Conditional Text")], 0) + : $cmp.elseifCondition + ? api_fragment(0, [api_static_fragment($fragment1(), 2)], 0) + : api_fragment( + 0, + [ + api_custom_element("c-default", _cDefault, stc0, [ + api_text("Else!"), + ]), + ], + 0 + ), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/mixed-elements/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/actual.html new file mode 100644 index 0000000000..207746baa6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/actual.html @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/ast.json new file mode 100644 index 0000000000..f281a8abb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/ast.json @@ -0,0 +1,560 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 13, + "endColumn": 12, + "start": 0, + "end": 510, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 13, + "startColumn": 1, + "endLine": 13, + "endColumn": 12, + "start": 499, + "end": 510 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 43, + "start": 15, + "end": 53 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Component", + "name": "c-custom", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 43, + "start": 15, + "end": 53, + "startTag": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 32, + "start": 15, + "end": 42 + }, + "endTag": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 43, + "start": 42, + "end": 53 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 7, + "name": "elseif", + "location": { + "startLine": 3, + "startColumn": 22, + "endLine": 3, + "endColumn": 41, + "start": 75, + "end": 94 + } + }, + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 11, + "endColumn": 23, + "start": 58, + "end": 453 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 22, + "endLine": 3, + "endColumn": 41, + "start": 75, + "end": 94 + }, + "children": [ + { + "type": "Component", + "name": "c-custom-elseif", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 11, + "endColumn": 23, + "start": 58, + "end": 453, + "startTag": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 42, + "start": 58, + "end": 95 + }, + "endTag": { + "startLine": 11, + "startColumn": 5, + "endLine": 11, + "endColumn": 23, + "start": 435, + "end": 453 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "If Text", + "value": { + "type": "Literal", + "value": "If Text" + }, + "location": { + "startLine": 3, + "startColumn": 42, + "endLine": 5, + "endColumn": 9, + "start": 95, + "end": 120 + } + }, + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 13, + "name": "showNestedIf", + "location": { + "startLine": 5, + "startColumn": 19, + "endLine": 5, + "endColumn": 40, + "start": 130, + "end": 151 + } + }, + "location": { + "startLine": 5, + "startColumn": 9, + "endLine": 8, + "endColumn": 20, + "start": 120, + "end": 311 + }, + "directiveLocation": { + "startLine": 5, + "startColumn": 19, + "endLine": 5, + "endColumn": 40, + "start": 130, + "end": 151 + }, + "children": [ + { + "type": "Component", + "name": "c-nested", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 5, + "startColumn": 9, + "endLine": 8, + "endColumn": 20, + "start": 120, + "end": 311, + "startTag": { + "startLine": 5, + "startColumn": 9, + "endLine": 5, + "endColumn": 41, + "start": 120, + "end": 152 + }, + "endTag": { + "startLine": 8, + "startColumn": 9, + "endLine": 8, + "endColumn": 20, + "start": 300, + "end": 311 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 15, + "name": "doubleNestedIf", + "location": { + "startLine": 6, + "startColumn": 30, + "endLine": 6, + "endColumn": 53, + "start": 182, + "end": 205 + } + }, + "location": { + "startLine": 6, + "startColumn": 13, + "endLine": 6, + "endColumn": 72, + "start": 165, + "end": 224 + }, + "directiveLocation": { + "startLine": 6, + "startColumn": 30, + "endLine": 6, + "endColumn": 53, + "start": 182, + "end": 205 + }, + "children": [ + { + "type": "Component", + "name": "c-double-nested", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 6, + "startColumn": 13, + "endLine": 6, + "endColumn": 72, + "start": 165, + "end": 224, + "startTag": { + "startLine": 6, + "startColumn": 13, + "endLine": 6, + "endColumn": 54, + "start": 165, + "end": 206 + }, + "endTag": { + "startLine": 6, + "startColumn": 54, + "endLine": 6, + "endColumn": 72, + "start": 206, + "end": 224 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 7, + "startColumn": 13, + "endLine": 7, + "endColumn": 67, + "start": 237, + "end": 291 + }, + "directiveLocation": { + "startLine": 7, + "startColumn": 35, + "endLine": 7, + "endColumn": 43, + "start": 259, + "end": 267 + }, + "children": [ + { + "type": "Component", + "name": "c-double-nested-else", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 7, + "startColumn": 13, + "endLine": 7, + "endColumn": 67, + "start": 237, + "end": 291, + "startTag": { + "startLine": 7, + "startColumn": 13, + "endLine": 7, + "endColumn": 44, + "start": 237, + "end": 268 + }, + "endTag": { + "startLine": 7, + "startColumn": 44, + "endLine": 7, + "endColumn": 67, + "start": 268, + "end": 291 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + } + ] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 13, + "name": "elseifNested", + "location": { + "startLine": 9, + "startColumn": 26, + "endLine": 9, + "endColumn": 51, + "start": 337, + "end": 362 + } + }, + "location": { + "startLine": 9, + "startColumn": 9, + "endLine": 9, + "endColumn": 70, + "start": 320, + "end": 381 + }, + "directiveLocation": { + "startLine": 9, + "startColumn": 26, + "endLine": 9, + "endColumn": 51, + "start": 337, + "end": 362 + }, + "children": [ + { + "type": "Component", + "name": "c-nested-elseif", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 9, + "startColumn": 9, + "endLine": 9, + "endColumn": 70, + "start": 320, + "end": 381, + "startTag": { + "startLine": 9, + "startColumn": 9, + "endLine": 9, + "endColumn": 52, + "start": 320, + "end": 363 + }, + "endTag": { + "startLine": 9, + "startColumn": 52, + "endLine": 9, + "endColumn": 70, + "start": 363, + "end": 381 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 10, + "startColumn": 9, + "endLine": 10, + "endColumn": 49, + "start": 390, + "end": 430 + }, + "directiveLocation": { + "startLine": 10, + "startColumn": 24, + "endLine": 10, + "endColumn": 32, + "start": 405, + "end": 413 + }, + "children": [ + { + "type": "Component", + "name": "c-nested-else", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 10, + "startColumn": 9, + "endLine": 10, + "endColumn": 49, + "start": 390, + "end": 430, + "startTag": { + "startLine": 10, + "startColumn": 9, + "endLine": 10, + "endColumn": 33, + "start": 390, + "end": 414 + }, + "endTag": { + "startLine": 10, + "startColumn": 33, + "endLine": 10, + "endColumn": 49, + "start": 414, + "end": 430 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + } + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 12, + "startColumn": 5, + "endLine": 12, + "endColumn": 45, + "start": 458, + "end": 498 + }, + "directiveLocation": { + "startLine": 12, + "startColumn": 20, + "endLine": 12, + "endColumn": 28, + "start": 473, + "end": 481 + }, + "children": [ + { + "type": "Component", + "name": "c-custom-else", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 12, + "startColumn": 5, + "endLine": 12, + "endColumn": 45, + "start": 458, + "end": 498, + "startTag": { + "startLine": 12, + "startColumn": 5, + "endLine": 12, + "endColumn": 29, + "start": 458, + "end": 482 + }, + "endTag": { + "startLine": 12, + "startColumn": 29, + "endLine": 12, + "endColumn": 45, + "start": 482, + "end": 498 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/expected.js new file mode 100644 index 0000000000..5ef9c96356 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/expected.js @@ -0,0 +1,107 @@ +import _cCustom from "c/custom"; +import _cDoubleNested from "c/doubleNested"; +import _cDoubleNestedElse from "c/doubleNestedElse"; +import _cNested from "c/nested"; +import _cNestedElseif from "c/nestedElseif"; +import _cNestedElse from "c/nestedElse"; +import _cCustomElseif from "c/customElseif"; +import _cCustomElse from "c/customElse"; +import { registerTemplate } from "lwc"; +const stc0 = { + key: 1, +}; +const stc1 = { + key: 2, +}; +const stc2 = { + key: 4, +}; +const stc3 = { + key: 6, +}; +const stc4 = { + key: 7, +}; +const stc5 = { + key: 8, +}; +const stc6 = { + key: 9, +}; +const stc7 = { + key: 10, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { c: api_custom_element, fr: api_fragment, t: api_text } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_custom_element("c-custom", _cCustom, stc0)], 0) + : $cmp.elseif + ? api_fragment( + 0, + [ + api_custom_element("c-custom-elseif", _cCustomElseif, stc1, [ + api_text("If Text"), + $cmp.showNestedIf + ? api_fragment( + 3, + [ + api_custom_element("c-nested", _cNested, stc2, [ + $cmp.doubleNestedIf + ? api_fragment( + 5, + [ + api_custom_element( + "c-double-nested", + _cDoubleNested, + stc3 + ), + ], + 0 + ) + : api_fragment( + 5, + [ + api_custom_element( + "c-double-nested-else", + _cDoubleNestedElse, + stc4 + ), + ], + 0 + ), + ]), + ], + 0 + ) + : $cmp.elseifNested + ? api_fragment( + 3, + [ + api_custom_element( + "c-nested-elseif", + _cNestedElseif, + stc5 + ), + ], + 0 + ) + : api_fragment( + 3, + [api_custom_element("c-nested-else", _cNestedElse, stc6)], + 0 + ), + ]), + ], + 0 + ) + : api_fragment( + 0, + [api_custom_element("c-custom-else", _cCustomElse, stc7)], + 0 + ), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/nested/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/actual.html new file mode 100644 index 0000000000..36ed011564 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/actual.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/ast.json new file mode 100644 index 0000000000..ad8f740076 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/ast.json @@ -0,0 +1,133 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 0, + "end": 142, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 5, + "startColumn": 1, + "endLine": 5, + "endColumn": 12, + "start": 131, + "end": 142 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 59, + "start": 15, + "end": 69 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Text", + "raw": "Conditional Text", + "value": { + "type": "Literal", + "value": "Conditional Text" + }, + "location": { + "startLine": 2, + "startColumn": 32, + "endLine": 2, + "endColumn": 48, + "start": 42, + "end": 58 + } + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 4, + "startColumn": 5, + "endLine": 4, + "endColumn": 40, + "start": 95, + "end": 130 + }, + "directiveLocation": { + "startLine": 4, + "startColumn": 15, + "endLine": 4, + "endColumn": 23, + "start": 105, + "end": 113 + }, + "children": [ + { + "type": "Text", + "raw": "Else!", + "value": { + "type": "Literal", + "value": "Else!" + }, + "location": { + "startLine": 4, + "startColumn": 24, + "endLine": 4, + "endColumn": 29, + "start": 114, + "end": 119 + } + } + ] + } + }, + { + "type": "Comment", + "raw": " Comment ", + "value": " Comment ", + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 3, + "endColumn": 21, + "start": 74, + "end": 90 + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/expected.js new file mode 100644 index 0000000000..2be1cdb2ee --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/expected.js @@ -0,0 +1,12 @@ +import { registerTemplate } from "lwc"; +function tmpl($api, $cmp, $slotset, $ctx) { + const { t: api_text, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment(0, [api_text("Conditional Text")], 0) + : api_fragment(0, [api_text("Else!")], 0), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-disabled/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/actual.html new file mode 100644 index 0000000000..36ed011564 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/actual.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/config.json new file mode 100644 index 0000000000..64e77756cd --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/config.json @@ -0,0 +1,3 @@ +{ + "preserveHtmlComments": true +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/metadata.json new file mode 100644 index 0000000000..6a5b35a636 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/preserve-comments/preserve-comments-enabled/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1165, + "message": "LWC1165: 'lwc:else' directive must be used immediately after an element with 'lwc:if' or 'lwc:elseif'. No such element found.", + "level": 1, + "location": { + "line": 4, + "column": 5, + "start": 95, + "length": 35 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/no-directives-in-slots/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/no-directives-in-slots/actual.html new file mode 100644 index 0000000000..317c5cd7cd --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/no-directives-in-slots/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/no-directives-in-slots/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/no-directives-in-slots/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/no-directives-in-slots/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/no-directives-in-slots/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/no-directives-in-slots/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/no-directives-in-slots/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/no-directives-in-slots/metadata.json new file mode 100644 index 0000000000..0da08c0eb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/no-directives-in-slots/metadata.json @@ -0,0 +1,26 @@ +{ + "warnings": [ + { + "code": 1082, + "message": "LWC1082: Slot tag can't be associated with directives", + "level": 1, + "location": { + "line": 2, + "column": 5, + "start": 15, + "length": 56 + } + }, + { + "code": 1082, + "message": "LWC1082: Slot tag can't be associated with directives", + "level": 1, + "location": { + "line": 3, + "column": 5, + "start": 76, + "length": 46 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/actual.html new file mode 100644 index 0000000000..5264fa74bb --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/actual.html @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/ast.json new file mode 100644 index 0000000000..a9e1076860 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/ast.json @@ -0,0 +1,451 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 21, + "endColumn": 12, + "start": 0, + "end": 540, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 21, + "startColumn": 1, + "endLine": 21, + "endColumn": 12, + "start": 529, + "end": 540 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 10, + "name": "condition", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 33, + "start": 25, + "end": 43 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 4, + "endColumn": 16, + "start": 15, + "end": 85 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 33, + "start": 25, + "end": 43 + }, + "children": [ + { + "type": "Text", + "raw": "Conditional Text", + "value": { + "type": "Literal", + "value": "Conditional Text" + }, + "location": { + "startLine": 2, + "startColumn": 34, + "endLine": 4, + "endColumn": 5, + "start": 44, + "end": 74 + } + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 13, + "name": "altCondition", + "location": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 40, + "start": 100, + "end": 125 + } + }, + "location": { + "startLine": 5, + "startColumn": 5, + "endLine": 9, + "endColumn": 16, + "start": 90, + "end": 217 + }, + "directiveLocation": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 40, + "start": 100, + "end": 125 + }, + "children": [ + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 6, + "startColumn": 9, + "endLine": 8, + "endColumn": 15, + "start": 135, + "end": 201, + "startTag": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 14, + "start": 135, + "end": 140 + }, + "endTag": { + "startLine": 8, + "startColumn": 9, + "endLine": 8, + "endColumn": 15, + "start": 195, + "end": 201 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "outside-slot", + "location": { + "startLine": 7, + "startColumn": 13, + "endLine": 7, + "endColumn": 46, + "start": 153, + "end": 186, + "startTag": { + "startLine": 7, + "startColumn": 13, + "endLine": 7, + "endColumn": 39, + "start": 153, + "end": 179 + }, + "endTag": { + "startLine": 7, + "startColumn": 39, + "endLine": 7, + "endColumn": 46, + "start": 179, + "end": 186 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "outside-slot" + }, + "location": { + "startLine": 7, + "startColumn": 19, + "endLine": 7, + "endColumn": 38, + "start": 159, + "end": 178 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 10, + "startColumn": 5, + "endLine": 12, + "endColumn": 16, + "start": 222, + "end": 299 + }, + "directiveLocation": { + "startLine": 10, + "startColumn": 15, + "endLine": 10, + "endColumn": 23, + "start": 232, + "end": 240 + }, + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "outside-slot", + "location": { + "startLine": 11, + "startColumn": 9, + "endLine": 11, + "endColumn": 42, + "start": 250, + "end": 283, + "startTag": { + "startLine": 11, + "startColumn": 9, + "endLine": 11, + "endColumn": 35, + "start": 250, + "end": 276 + }, + "endTag": { + "startLine": 11, + "startColumn": 35, + "endLine": 11, + "endColumn": 42, + "start": 276, + "end": 283 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "outside-slot" + }, + "location": { + "startLine": 11, + "startColumn": 15, + "endLine": 11, + "endColumn": 34, + "start": 256, + "end": 275 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + } + }, + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 17, + "name": "anotherCondition", + "location": { + "startLine": 13, + "startColumn": 15, + "endLine": 13, + "endColumn": 40, + "start": 314, + "end": 339 + } + }, + "location": { + "startLine": 13, + "startColumn": 5, + "endLine": 15, + "endColumn": 16, + "start": 304, + "end": 389 + }, + "directiveLocation": { + "startLine": 13, + "startColumn": 15, + "endLine": 13, + "endColumn": 40, + "start": 314, + "end": 339 + }, + "children": [ + { + "type": "Text", + "raw": "Another Conditional Text", + "value": { + "type": "Literal", + "value": "Another Conditional Text" + }, + "location": { + "startLine": 13, + "startColumn": 41, + "endLine": 15, + "endColumn": 5, + "start": 340, + "end": 378 + } + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 20, + "name": "anotherAltCondition", + "location": { + "startLine": 16, + "startColumn": 15, + "endLine": 16, + "endColumn": 47, + "start": 404, + "end": 436 + } + }, + "location": { + "startLine": 16, + "startColumn": 5, + "endLine": 20, + "endColumn": 16, + "start": 394, + "end": 528 + }, + "directiveLocation": { + "startLine": 16, + "startColumn": 15, + "endLine": 16, + "endColumn": 47, + "start": 404, + "end": 436 + }, + "children": [ + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 17, + "startColumn": 9, + "endLine": 19, + "endColumn": 15, + "start": 446, + "end": 512, + "startTag": { + "startLine": 17, + "startColumn": 9, + "endLine": 17, + "endColumn": 14, + "start": 446, + "end": 451 + }, + "endTag": { + "startLine": 19, + "startColumn": 9, + "endLine": 19, + "endColumn": 15, + "start": 506, + "end": 512 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "outside-slot", + "location": { + "startLine": 18, + "startColumn": 13, + "endLine": 18, + "endColumn": 46, + "start": 464, + "end": 497, + "startTag": { + "startLine": 18, + "startColumn": 13, + "endLine": 18, + "endColumn": 39, + "start": 464, + "end": 490 + }, + "endTag": { + "startLine": 18, + "startColumn": 39, + "endLine": 18, + "endColumn": 46, + "start": 490, + "end": 497 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "outside-slot" + }, + "location": { + "startLine": 18, + "startColumn": 19, + "endLine": 18, + "endColumn": 38, + "start": 470, + "end": 489 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/expected.js new file mode 100644 index 0000000000..8d5abdb865 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/expected.js @@ -0,0 +1,61 @@ +import { registerTemplate } from "lwc"; +const stc0 = { + key: 1, +}; +const stc1 = { + attrs: { + name: "outside-slot", + }, + key: 2, +}; +const stc2 = []; +const stc3 = { + attrs: { + name: "outside-slot", + }, + key: 3, +}; +const stc4 = { + key: 5, +}; +const stc5 = { + attrs: { + name: "outside-slot", + }, + key: 6, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { t: api_text, fr: api_fragment, s: api_slot, h: api_element } = $api; + return [ + $cmp.condition + ? api_fragment(0, [api_text("Conditional Text")], 0) + : $cmp.altCondition + ? api_fragment( + 0, + [ + api_element("div", stc0, [ + api_slot("outside-slot", stc1, stc2, $slotset), + ]), + ], + 0 + ) + : api_fragment(0, [api_slot("outside-slot", stc3, stc2, $slotset)], 0), + $cmp.anotherCondition + ? api_fragment(4, [api_text("Another Conditional Text")], 0) + : $cmp.anotherAltCondition + ? api_fragment( + 4, + [ + api_element("div", stc4, [ + api_slot("outside-slot", stc5, stc2, $slotset), + ]), + ], + 0 + ) + : null, + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.slots = ["outside-slot"]; +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/metadata.json new file mode 100644 index 0000000000..cdf228d12c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/not-in-same-condition-tree/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1137, + "message": "LWC1137: Invalid duplicate slot (name=\"outside-slot\").", + "level": 2, + "location": { + "line": 18, + "column": 13, + "start": 464, + "length": 33 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/actual.html new file mode 100644 index 0000000000..17e5c9edc0 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/actual.html @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/ast.json new file mode 100644 index 0000000000..80fb0084c3 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/ast.json @@ -0,0 +1,243 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 11, + "endColumn": 12, + "start": 0, + "end": 252, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 11, + "startColumn": 1, + "endLine": 11, + "endColumn": 12, + "start": 241, + "end": 252 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 10, + "name": "condition", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 33, + "start": 25, + "end": 43 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 7, + "endColumn": 16, + "start": 15, + "end": 175 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 33, + "start": 25, + "end": 43 + }, + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "nested-slot", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 41, + "start": 53, + "end": 85, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 34, + "start": 53, + "end": 78 + }, + "endTag": { + "startLine": 3, + "startColumn": 34, + "endLine": 3, + "endColumn": 41, + "start": 78, + "end": 85 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "nested-slot" + }, + "location": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 33, + "start": 59, + "end": 77 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + }, + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 4, + "startColumn": 9, + "endLine": 6, + "endColumn": 15, + "start": 94, + "end": 159, + "startTag": { + "startLine": 4, + "startColumn": 9, + "endLine": 4, + "endColumn": 14, + "start": 94, + "end": 99 + }, + "endTag": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 15, + "start": 153, + "end": 159 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "nested-slot", + "location": { + "startLine": 5, + "startColumn": 13, + "endLine": 5, + "endColumn": 45, + "start": 112, + "end": 144, + "startTag": { + "startLine": 5, + "startColumn": 13, + "endLine": 5, + "endColumn": 38, + "start": 112, + "end": 137 + }, + "endTag": { + "startLine": 5, + "startColumn": 38, + "endLine": 5, + "endColumn": 45, + "start": 137, + "end": 144 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "nested-slot" + }, + "location": { + "startLine": 5, + "startColumn": 19, + "endLine": 5, + "endColumn": 37, + "start": 118, + "end": 136 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 8, + "startColumn": 5, + "endLine": 10, + "endColumn": 16, + "start": 180, + "end": 240 + }, + "directiveLocation": { + "startLine": 8, + "startColumn": 15, + "endLine": 8, + "endColumn": 23, + "start": 190, + "end": 198 + }, + "children": [ + { + "type": "Text", + "raw": "Alternative Text", + "value": { + "type": "Literal", + "value": "Alternative Text" + }, + "location": { + "startLine": 8, + "startColumn": 24, + "endLine": 10, + "endColumn": 5, + "start": 199, + "end": 229 + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/expected.js new file mode 100644 index 0000000000..7e305d7fb8 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/expected.js @@ -0,0 +1,38 @@ +import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + name: "nested-slot", + }, + key: 1, +}; +const stc1 = []; +const stc2 = { + key: 2, +}; +const stc3 = { + attrs: { + name: "nested-slot", + }, + key: 3, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { s: api_slot, h: api_element, fr: api_fragment, t: api_text } = $api; + return [ + $cmp.condition + ? api_fragment( + 0, + [ + api_slot("nested-slot", stc0, stc1, $slotset), + api_element("div", stc2, [ + api_slot("nested-slot", stc3, stc1, $slotset), + ]), + ], + 0 + ) + : api_fragment(0, [api_text("Alternative Text")], 0), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.slots = ["nested-slot"]; +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/metadata.json new file mode 100644 index 0000000000..a40aae4f44 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/same-branch-condition-tree/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1137, + "message": "LWC1137: Invalid duplicate slot (name=\"nested-slot\").", + "level": 2, + "location": { + "line": 5, + "column": 13, + "start": 112, + "length": 32 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/actual.html new file mode 100644 index 0000000000..6c424a31e1 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/actual.html @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/ast.json new file mode 100644 index 0000000000..1bca535439 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/ast.json @@ -0,0 +1,292 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 11, + "endColumn": 12, + "start": 0, + "end": 214, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 11, + "startColumn": 1, + "endLine": 11, + "endColumn": 12, + "start": 203, + "end": 214 + } + }, + "directives": [], + "children": [ + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 6, + "endColumn": 11, + "start": 15, + "end": 110, + "startTag": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 10, + "start": 15, + "end": 20 + }, + "endTag": { + "startLine": 6, + "startColumn": 5, + "endLine": 6, + "endColumn": 11, + "start": 104, + "end": 110 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 5, + "endColumn": 15, + "start": 29, + "end": 99, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 14, + "start": 29, + "end": 34 + }, + "endTag": { + "startLine": 5, + "startColumn": 9, + "endLine": 5, + "endColumn": 15, + "start": 93, + "end": 99 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "conditional-slot", + "location": { + "startLine": 4, + "startColumn": 13, + "endLine": 4, + "endColumn": 50, + "start": 47, + "end": 84, + "startTag": { + "startLine": 4, + "startColumn": 13, + "endLine": 4, + "endColumn": 43, + "start": 47, + "end": 77 + }, + "endTag": { + "startLine": 4, + "startColumn": 43, + "endLine": 4, + "endColumn": 50, + "start": 77, + "end": 84 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "conditional-slot" + }, + "location": { + "startLine": 4, + "startColumn": 19, + "endLine": 4, + "endColumn": 42, + "start": 53, + "end": 76 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + ] + }, + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 7, + "startColumn": 5, + "endLine": 7, + "endColumn": 25, + "start": 115, + "end": 135, + "startTag": { + "startLine": 7, + "startColumn": 5, + "endLine": 7, + "endColumn": 10, + "start": 115, + "end": 120 + }, + "endTag": { + "startLine": 7, + "startColumn": 19, + "endLine": 7, + "endColumn": 25, + "start": 129, + "end": 135 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Separator", + "value": { + "type": "Literal", + "value": "Separator" + }, + "location": { + "startLine": 7, + "startColumn": 10, + "endLine": 7, + "endColumn": 19, + "start": 120, + "end": 129 + } + } + ] + }, + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 8, + "startColumn": 5, + "endLine": 10, + "endColumn": 11, + "start": 140, + "end": 202, + "startTag": { + "startLine": 8, + "startColumn": 5, + "endLine": 8, + "endColumn": 10, + "start": 140, + "end": 145 + }, + "endTag": { + "startLine": 10, + "startColumn": 5, + "endLine": 10, + "endColumn": 11, + "start": 196, + "end": 202 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "conditional-slot", + "location": { + "startLine": 9, + "startColumn": 9, + "endLine": 9, + "endColumn": 46, + "start": 154, + "end": 191, + "startTag": { + "startLine": 9, + "startColumn": 9, + "endLine": 9, + "endColumn": 39, + "start": 154, + "end": 184 + }, + "endTag": { + "startLine": 9, + "startColumn": 39, + "endLine": 9, + "endColumn": 46, + "start": 184, + "end": 191 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "conditional-slot" + }, + "location": { + "startLine": 9, + "startColumn": 15, + "endLine": 9, + "endColumn": 38, + "start": 160, + "end": 183 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/expected.js new file mode 100644 index 0000000000..12beb4b514 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/expected.js @@ -0,0 +1,42 @@ +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment`Separator`; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + attrs: { + name: "conditional-slot", + }, + key: 2, +}; +const stc3 = []; +const stc4 = { + key: 5, +}; +const stc5 = { + attrs: { + name: "conditional-slot", + }, + key: 6, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { s: api_slot, h: api_element, st: api_static_fragment } = $api; + return [ + api_element("div", stc0, [ + api_element("div", stc1, [ + api_slot("conditional-slot", stc2, stc3, $slotset), + ]), + ]), + api_static_fragment($fragment1(), 4), + api_element("div", stc4, [ + api_slot("conditional-slot", stc5, stc3, $slotset), + ]), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.slots = ["conditional-slot"]; +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/metadata.json new file mode 100644 index 0000000000..03aeef9f81 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/duplicate-slots-warning/simple/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1137, + "message": "LWC1137: Invalid duplicate slot (name=\"conditional-slot\").", + "level": 2, + "location": { + "line": 9, + "column": 9, + "start": 154, + "length": 37 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/actual.html new file mode 100644 index 0000000000..8dbd7df7c2 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/actual.html @@ -0,0 +1,31 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/ast.json new file mode 100644 index 0000000000..181be756e2 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/ast.json @@ -0,0 +1,768 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 31, + "endColumn": 12, + "start": 0, + "end": 986, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 31, + "startColumn": 1, + "endLine": 31, + "endColumn": 12, + "start": 975, + "end": 986 + } + }, + "directives": [], + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "outer-slot", + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 36, + "start": 15, + "end": 46, + "startTag": { + "startLine": 2, + "startColumn": 5, + "endLine": 2, + "endColumn": 29, + "start": 15, + "end": 39 + }, + "endTag": { + "startLine": 2, + "startColumn": 29, + "endLine": 2, + "endColumn": 36, + "start": 39, + "end": 46 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "outer-slot" + }, + "location": { + "startLine": 2, + "startColumn": 11, + "endLine": 2, + "endColumn": 28, + "start": 21, + "end": 38 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + }, + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 10, + "name": "condition", + "location": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 33, + "start": 61, + "end": 79 + } + }, + "location": { + "startLine": 3, + "startColumn": 5, + "endLine": 26, + "endColumn": 16, + "start": 51, + "end": 847 + }, + "directiveLocation": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 33, + "start": 61, + "end": 79 + }, + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 7, + "name": "nested", + "location": { + "startLine": 4, + "startColumn": 19, + "endLine": 4, + "endColumn": 34, + "start": 99, + "end": 114 + } + }, + "location": { + "startLine": 4, + "startColumn": 9, + "endLine": 7, + "endColumn": 20, + "start": 89, + "end": 216 + }, + "directiveLocation": { + "startLine": 4, + "startColumn": 19, + "endLine": 4, + "endColumn": 34, + "start": 99, + "end": 114 + }, + "children": [ + { + "type": "Text", + "raw": "Conditional Nested Text", + "value": { + "type": "Literal", + "value": "Conditional Nested Text" + }, + "location": { + "startLine": 4, + "startColumn": 35, + "endLine": 6, + "endColumn": 13, + "start": 115, + "end": 164 + } + }, + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "nested-slot", + "location": { + "startLine": 6, + "startColumn": 13, + "endLine": 6, + "endColumn": 45, + "start": 164, + "end": 196, + "startTag": { + "startLine": 6, + "startColumn": 13, + "endLine": 6, + "endColumn": 38, + "start": 164, + "end": 189 + }, + "endTag": { + "startLine": 6, + "startColumn": 38, + "endLine": 6, + "endColumn": 45, + "start": 189, + "end": 196 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "nested-slot" + }, + "location": { + "startLine": 6, + "startColumn": 19, + "endLine": 6, + "endColumn": 37, + "start": 170, + "end": 188 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 8, + "startColumn": 9, + "endLine": 24, + "endColumn": 20, + "start": 225, + "end": 785 + }, + "directiveLocation": { + "startLine": 8, + "startColumn": 19, + "endLine": 8, + "endColumn": 27, + "start": 235, + "end": 243 + }, + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 13, + "name": "doubleNested", + "location": { + "startLine": 9, + "startColumn": 23, + "endLine": 9, + "endColumn": 44, + "start": 267, + "end": 288 + } + }, + "location": { + "startLine": 9, + "startColumn": 13, + "endLine": 11, + "endColumn": 24, + "start": 257, + "end": 343 + }, + "directiveLocation": { + "startLine": 9, + "startColumn": 23, + "endLine": 9, + "endColumn": 44, + "start": 267, + "end": 288 + }, + "children": [ + { + "type": "Text", + "raw": "Double Nested", + "value": { + "type": "Literal", + "value": "Double Nested" + }, + "location": { + "startLine": 9, + "startColumn": 45, + "endLine": 11, + "endColumn": 13, + "start": 289, + "end": 332 + } + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 16, + "name": "doubleNestedAlt", + "location": { + "startLine": 12, + "startColumn": 23, + "endLine": 12, + "endColumn": 51, + "start": 366, + "end": 394 + } + }, + "location": { + "startLine": 12, + "startColumn": 13, + "endLine": 19, + "endColumn": 24, + "start": 356, + "end": 639 + }, + "directiveLocation": { + "startLine": 12, + "startColumn": 23, + "endLine": 12, + "endColumn": 51, + "start": 366, + "end": 394 + }, + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 13, + "name": "tripleNested", + "location": { + "startLine": 13, + "startColumn": 22, + "endLine": 13, + "endColumn": 43, + "start": 417, + "end": 438 + } + }, + "location": { + "startLine": 13, + "startColumn": 17, + "endLine": 18, + "endColumn": 23, + "start": 412, + "end": 615 + }, + "directiveLocation": { + "startLine": 13, + "startColumn": 22, + "endLine": 13, + "endColumn": 43, + "start": 417, + "end": 438 + }, + "children": [ + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 13, + "startColumn": 17, + "endLine": 18, + "endColumn": 23, + "start": 412, + "end": 615, + "startTag": { + "startLine": 13, + "startColumn": 17, + "endLine": 13, + "endColumn": 44, + "start": 412, + "end": 439 + }, + "endTag": { + "startLine": 18, + "startColumn": 17, + "endLine": 18, + "endColumn": 23, + "start": 609, + "end": 615 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Element", + "name": "div", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 14, + "startColumn": 21, + "endLine": 17, + "endColumn": 27, + "start": 460, + "end": 592, + "startTag": { + "startLine": 14, + "startColumn": 21, + "endLine": 14, + "endColumn": 26, + "start": 460, + "end": 465 + }, + "endTag": { + "startLine": 17, + "startColumn": 21, + "endLine": 17, + "endColumn": 27, + "start": 586, + "end": 592 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Triple Nested Text", + "value": { + "type": "Literal", + "value": "Triple Nested Text" + }, + "location": { + "startLine": 14, + "startColumn": 26, + "endLine": 16, + "endColumn": 25, + "start": 465, + "end": 533 + } + }, + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "nested-slot", + "location": { + "startLine": 16, + "startColumn": 25, + "endLine": 16, + "endColumn": 57, + "start": 533, + "end": 565, + "startTag": { + "startLine": 16, + "startColumn": 25, + "endLine": 16, + "endColumn": 50, + "start": 533, + "end": 558 + }, + "endTag": { + "startLine": 16, + "startColumn": 50, + "endLine": 16, + "endColumn": 57, + "start": 558, + "end": 565 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "nested-slot" + }, + "location": { + "startLine": 16, + "startColumn": 31, + "endLine": 16, + "endColumn": 49, + "start": 539, + "end": 557 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + ] + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 20, + "startColumn": 13, + "endLine": 23, + "endColumn": 24, + "start": 652, + "end": 765 + }, + "directiveLocation": { + "startLine": 20, + "startColumn": 23, + "endLine": 20, + "endColumn": 31, + "start": 662, + "end": 670 + }, + "children": [ + { + "type": "Text", + "raw": "Else", + "value": { + "type": "Literal", + "value": "Else" + }, + "location": { + "startLine": 20, + "startColumn": 32, + "endLine": 22, + "endColumn": 17, + "start": 671, + "end": 709 + } + }, + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "nested-slot", + "location": { + "startLine": 22, + "startColumn": 17, + "endLine": 22, + "endColumn": 49, + "start": 709, + "end": 741, + "startTag": { + "startLine": 22, + "startColumn": 17, + "endLine": 22, + "endColumn": 42, + "start": 709, + "end": 734 + }, + "endTag": { + "startLine": 22, + "startColumn": 42, + "endLine": 22, + "endColumn": 49, + "start": 734, + "end": 741 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "nested-slot" + }, + "location": { + "startLine": 22, + "startColumn": 23, + "endLine": 22, + "endColumn": 41, + "start": 715, + "end": 733 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + } + } + ] + } + }, + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "conditional-slot", + "location": { + "startLine": 25, + "startColumn": 9, + "endLine": 25, + "endColumn": 46, + "start": 794, + "end": 831, + "startTag": { + "startLine": 25, + "startColumn": 9, + "endLine": 25, + "endColumn": 39, + "start": 794, + "end": 824 + }, + "endTag": { + "startLine": 25, + "startColumn": 39, + "endLine": 25, + "endColumn": 46, + "start": 824, + "end": 831 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "conditional-slot" + }, + "location": { + "startLine": 25, + "startColumn": 15, + "endLine": 25, + "endColumn": 38, + "start": 800, + "end": 823 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 27, + "startColumn": 5, + "endLine": 30, + "endColumn": 16, + "start": 852, + "end": 974 + }, + "directiveLocation": { + "startLine": 27, + "startColumn": 15, + "endLine": 27, + "endColumn": 23, + "start": 862, + "end": 870 + }, + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "conditional-slot", + "location": { + "startLine": 28, + "startColumn": 9, + "endLine": 28, + "endColumn": 46, + "start": 880, + "end": 917, + "startTag": { + "startLine": 28, + "startColumn": 9, + "endLine": 28, + "endColumn": 39, + "start": 880, + "end": 910 + }, + "endTag": { + "startLine": 28, + "startColumn": 39, + "endLine": 28, + "endColumn": 46, + "start": 910, + "end": 917 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "conditional-slot" + }, + "location": { + "startLine": 28, + "startColumn": 15, + "endLine": 28, + "endColumn": 38, + "start": 886, + "end": 909 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + }, + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "nested-slot", + "location": { + "startLine": 29, + "startColumn": 9, + "endLine": 29, + "endColumn": 41, + "start": 926, + "end": 958, + "startTag": { + "startLine": 29, + "startColumn": 9, + "endLine": 29, + "endColumn": 34, + "start": 926, + "end": 951 + }, + "endTag": { + "startLine": 29, + "startColumn": 34, + "endLine": 29, + "endColumn": 41, + "start": 951, + "end": 958 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "nested-slot" + }, + "location": { + "startLine": 29, + "startColumn": 15, + "endLine": 29, + "endColumn": 33, + "start": 932, + "end": 950 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/expected.js new file mode 100644 index 0000000000..7a44fc5411 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/expected.js @@ -0,0 +1,127 @@ +import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + name: "outer-slot", + }, + key: 0, +}; +const stc1 = []; +const stc2 = { + attrs: { + name: "nested-slot", + }, + key: 3, +}; +const stc3 = { + key: 6, +}; +const stc4 = { + key: 7, +}; +const stc5 = { + attrs: { + name: "nested-slot", + }, + key: 8, +}; +const stc6 = { + attrs: { + name: "nested-slot", + }, + key: 9, +}; +const stc7 = { + attrs: { + name: "conditional-slot", + }, + key: 10, +}; +const stc8 = { + attrs: { + name: "conditional-slot", + }, + key: 11, +}; +const stc9 = { + attrs: { + name: "nested-slot", + }, + key: 12, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { s: api_slot, t: api_text, fr: api_fragment, h: api_element } = $api; + return [ + api_slot("outer-slot", stc0, stc1, $slotset), + $cmp.condition + ? api_fragment( + 1, + [ + $cmp.nested + ? api_fragment( + 2, + [ + api_text("Conditional Nested Text"), + api_slot("nested-slot", stc2, stc1, $slotset), + ], + 0 + ) + : api_fragment( + 2, + [ + $cmp.doubleNested + ? api_fragment(4, [api_text("Double Nested")], 0) + : $cmp.doubleNestedAlt + ? api_fragment( + 4, + [ + $cmp.tripleNested + ? api_fragment( + 5, + [ + api_element("div", stc3, [ + api_element("div", stc4, [ + api_text("Triple Nested Text"), + api_slot( + "nested-slot", + stc5, + stc1, + $slotset + ), + ]), + ]), + ], + 0 + ) + : null, + ], + 0 + ) + : api_fragment( + 4, + [ + api_text("Else"), + api_slot("nested-slot", stc6, stc1, $slotset), + ], + 0 + ), + ], + 0 + ), + api_slot("conditional-slot", stc7, stc1, $slotset), + ], + 0 + ) + : api_fragment( + 1, + [ + api_slot("conditional-slot", stc8, stc1, $slotset), + api_slot("nested-slot", stc9, stc1, $slotset), + ], + 0 + ), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.slots = ["conditional-slot", "nested-slot", "outer-slot"]; +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/complex/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/actual.html new file mode 100644 index 0000000000..10d0dbb145 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/actual.html @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/ast.json new file mode 100644 index 0000000000..c8d8a0ef46 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/ast.json @@ -0,0 +1,192 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 8, + "endColumn": 12, + "start": 0, + "end": 204, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 8, + "startColumn": 1, + "endLine": 8, + "endColumn": 12, + "start": 193, + "end": 204 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 10, + "name": "condition", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 33, + "start": 25, + "end": 43 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 4, + "endColumn": 16, + "start": 15, + "end": 106 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 33, + "start": 25, + "end": 43 + }, + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "conditional-slot", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 46, + "start": 53, + "end": 90, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 39, + "start": 53, + "end": 83 + }, + "endTag": { + "startLine": 3, + "startColumn": 39, + "endLine": 3, + "endColumn": 46, + "start": 83, + "end": 90 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "conditional-slot" + }, + "location": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 38, + "start": 59, + "end": 82 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 5, + "startColumn": 5, + "endLine": 7, + "endColumn": 16, + "start": 111, + "end": 192 + }, + "directiveLocation": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 23, + "start": 121, + "end": 129 + }, + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "conditional-slot", + "location": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 46, + "start": 139, + "end": 176, + "startTag": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 39, + "start": 139, + "end": 169 + }, + "endTag": { + "startLine": 6, + "startColumn": 39, + "endLine": 6, + "endColumn": 46, + "start": 169, + "end": 176 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "conditional-slot" + }, + "location": { + "startLine": 6, + "startColumn": 15, + "endLine": 6, + "endColumn": 38, + "start": 145, + "end": 168 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/expected.js new file mode 100644 index 0000000000..bbefb416c4 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/expected.js @@ -0,0 +1,30 @@ +import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + name: "conditional-slot", + }, + key: 1, +}; +const stc1 = []; +const stc2 = { + attrs: { + name: "conditional-slot", + }, + key: 2, +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { s: api_slot, fr: api_fragment } = $api; + return [ + $cmp.condition + ? api_fragment(0, [api_slot("conditional-slot", stc0, stc1, $slotset)], 0) + : api_fragment( + 0, + [api_slot("conditional-slot", stc2, stc1, $slotset)], + 0 + ), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.slots = ["conditional-slot"]; +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/slots/valid-duplicate-slot-names/simple/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/actual.html new file mode 100644 index 0000000000..2503d86b7b --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/actual.html @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/ast.json new file mode 100644 index 0000000000..de557961a5 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/ast.json @@ -0,0 +1,359 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 12, + "endColumn": 12, + "start": 0, + "end": 253, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 11, + "start": 0, + "end": 10 + }, + "endTag": { + "startLine": 12, + "startColumn": 1, + "endLine": 12, + "endColumn": 12, + "start": 242, + "end": 253 + } + }, + "directives": [], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 8, + "name": "visible", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 5, + "endColumn": 16, + "start": 15, + "end": 112 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 31, + "start": 25, + "end": 41 + }, + "children": [ + { + "type": "Text", + "raw": "Conditional Text", + "value": { + "type": "Literal", + "value": "Conditional Text" + }, + "location": { + "startLine": 2, + "startColumn": 32, + "endLine": 4, + "endColumn": 9, + "start": 42, + "end": 76 + } + }, + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 4, + "startColumn": 9, + "endLine": 4, + "endColumn": 29, + "start": 76, + "end": 96, + "startTag": { + "startLine": 4, + "startColumn": 9, + "endLine": 4, + "endColumn": 13, + "start": 76, + "end": 80 + }, + "endTag": { + "startLine": 4, + "startColumn": 24, + "endLine": 4, + "endColumn": 29, + "start": 91, + "end": 96 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "Happy days!", + "value": { + "type": "Literal", + "value": "Happy days!" + }, + "location": { + "startLine": 4, + "startColumn": 13, + "endLine": 4, + "endColumn": 24, + "start": 80, + "end": 91 + } + } + ] + } + ], + "else": { + "type": "ElseBlock", + "location": { + "startLine": 6, + "startColumn": 5, + "endLine": 9, + "endColumn": 16, + "start": 117, + "end": 202 + }, + "directiveLocation": { + "startLine": 6, + "startColumn": 15, + "endLine": 6, + "endColumn": 23, + "start": 127, + "end": 135 + }, + "children": [ + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 7, + "startColumn": 9, + "endLine": 7, + "endColumn": 26, + "start": 145, + "end": 162, + "startTag": { + "startLine": 7, + "startColumn": 9, + "endLine": 7, + "endColumn": 13, + "start": 145, + "end": 149 + }, + "endTag": { + "startLine": 7, + "startColumn": 21, + "endLine": 7, + "endColumn": 26, + "start": 157, + "end": 162 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "stranger", + "value": { + "type": "Literal", + "value": "stranger" + }, + "location": { + "startLine": 7, + "startColumn": 13, + "endLine": 7, + "endColumn": 21, + "start": 149, + "end": 157 + } + } + ] + }, + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 8, + "startColumn": 9, + "endLine": 8, + "endColumn": 24, + "start": 171, + "end": 186, + "startTag": { + "startLine": 8, + "startColumn": 9, + "endLine": 8, + "endColumn": 13, + "start": 171, + "end": 175 + }, + "endTag": { + "startLine": 8, + "startColumn": 19, + "endLine": 8, + "endColumn": 24, + "start": 181, + "end": 186 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "things", + "value": { + "type": "Literal", + "value": "things" + }, + "location": { + "startLine": 8, + "startColumn": 13, + "endLine": 8, + "endColumn": 19, + "start": 175, + "end": 181 + } + } + ] + } + ] + } + }, + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 10, + "startColumn": 5, + "endLine": 10, + "endColumn": 19, + "start": 207, + "end": 221, + "startTag": { + "startLine": 10, + "startColumn": 5, + "endLine": 10, + "endColumn": 9, + "start": 207, + "end": 211 + }, + "endTag": { + "startLine": 10, + "startColumn": 14, + "endLine": 10, + "endColumn": 19, + "start": 216, + "end": 221 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "hello", + "value": { + "type": "Literal", + "value": "hello" + }, + "location": { + "startLine": 10, + "startColumn": 9, + "endLine": 10, + "endColumn": 14, + "start": 211, + "end": 216 + } + } + ] + }, + { + "type": "Element", + "name": "h1", + "namespace": "http://www.w3.org/1999/xhtml", + "location": { + "startLine": 11, + "startColumn": 5, + "endLine": 11, + "endColumn": 20, + "start": 226, + "end": 241, + "startTag": { + "startLine": 11, + "startColumn": 5, + "endLine": 11, + "endColumn": 9, + "start": 226, + "end": 230 + }, + "endTag": { + "startLine": 11, + "startColumn": 15, + "endLine": 11, + "endColumn": 20, + "start": 236, + "end": 241 + } + }, + "attributes": [], + "properties": [], + "directives": [], + "listeners": [], + "children": [ + { + "type": "Text", + "raw": "world!", + "value": { + "type": "Literal", + "value": "world!" + }, + "location": { + "startLine": 11, + "startColumn": 9, + "endLine": 11, + "endColumn": 15, + "start": 230, + "end": 236 + } + } + ] + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/expected.js new file mode 100644 index 0000000000..b4f68c716b --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/expected.js @@ -0,0 +1,30 @@ +import { parseFragment, registerTemplate } from "lwc"; +const $fragment1 = parseFragment`Happy days!`; +const $fragment2 = parseFragment`stranger`; +const $fragment3 = parseFragment`things`; +const $fragment4 = parseFragment`hello`; +const $fragment5 = parseFragment`world!`; +function tmpl($api, $cmp, $slotset, $ctx) { + const { t: api_text, st: api_static_fragment, fr: api_fragment } = $api; + return [ + $cmp.visible + ? api_fragment( + 0, + [api_text("Conditional Text"), api_static_fragment($fragment1(), 2)], + 0 + ) + : api_fragment( + 0, + [ + api_static_fragment($fragment2(), 4), + api_static_fragment($fragment3(), 6), + ], + 0 + ), + api_static_fragment($fragment4(), 8), + api_static_fragment($fragment5(), 10), + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-lwc-if-else/with-siblings/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/codegen/helpers.ts b/packages/@lwc/template-compiler/src/codegen/helpers.ts index e2c19326de..c4adb37308 100644 --- a/packages/@lwc/template-compiler/src/codegen/helpers.ts +++ b/packages/@lwc/template-compiler/src/codegen/helpers.ts @@ -6,7 +6,14 @@ */ import * as t from '../shared/estree'; import { toPropertyName } from '../shared/utils'; -import { BaseElement, ChildNode, LWCDirectiveRenderMode, Node, Root } from '../shared/types'; +import { + BaseElement, + ChildNode, + LWCDirectiveRenderMode, + Node, + ParentNode, + Root, +} from '../shared/types'; import { isParentNode, isSlot, @@ -16,6 +23,8 @@ import { isElement, isText, isComment, + isIfBlock, + isConditionalParentBlock, } from '../shared/ast'; import { TEMPLATE_FUNCTION_NAME, TEMPLATE_PARAMS } from '../shared/constants'; @@ -53,32 +62,45 @@ export function objectToAST( ); } -export function containsDynamicChildren(children: ChildNode[]): boolean { - return children.some((child) => { - if (isForBlock(child) || isIf(child)) { - return containsDynamicChildren(child.children); +export function containsDynamicChildren(parent: ParentNode): boolean { + const hasDynamicChildren = parent.children.some((child) => { + // The child in the children array will only ever contain an IfBlock. + // ElseIfBlock and ElseBlock are chained together starting from the IfBlock. + if (isForBlock(child) || isIf(child) || isIfBlock(child)) { + return containsDynamicChildren(child); } return false; }); + + // In order to check the if-elseif-else chain fully, if the parent is an IfBlock or ElseIfBlock + // the else branch must be checked as well. + const elseConditionHasDynamicChildren = + isConditionalParentBlock(parent) && parent.else + ? containsDynamicChildren(parent.else) + : false; + + return hasDynamicChildren || elseConditionHasDynamicChildren; } /** * Returns true if the children should be flattened. * - * Children should be flattened if they contain an iterator, - * a dynamic directive or a slot inside a light dom element. + * This function searches through the children to determine if flattening needs to occur in the runtime. + * Children should be flattened if they contain an iterator, a dynamic directive or a slot inside a light dom element. */ export function shouldFlatten(codeGen: CodeGen, children: ChildNode[]): boolean { - return children.some( - (child) => + return children.some((child) => { + return ( + // ForBlock will generate a list of iterable vnodes isForBlock(child) || - (isParentNode(child) && - // If node is only a control flow node and does not map to a stand alone element. - // Search children to determine if it should be flattened. - ((isIf(child) && shouldFlatten(codeGen, child.children)) || - (codeGen.renderMode === LWCDirectiveRenderMode.light && isSlot(child)))) - ); + // light DOM slots + (isSlot(child) && codeGen.renderMode === LWCDirectiveRenderMode.light) || + // If node is only a control flow node and does not map to a stand alone element. + // Search children to determine if it should be flattened. + (isIf(child) && shouldFlatten(codeGen, child.children)) + ); + }); } /** @@ -264,13 +286,18 @@ function collectStaticNodes(node: ChildNode, staticNodes: Set, state: } else if (isComment(node)) { nodeIsStatic = true; } else { - // it is ForBlock | If | BaseElement + // it is ElseBlock | ForBlock | If | BaseElement node.children.forEach((childNode) => { collectStaticNodes(childNode, staticNodes, state); childrenAreStatic = childrenAreStatic && staticNodes.has(childNode); }); + // for IfBlock and ElseifBlock, traverse down the else branch + if (isConditionalParentBlock(node) && node.else) { + collectStaticNodes(node.else, staticNodes, state); + } + nodeIsStatic = isBaseElement(node) && !isCustomRendererHookRequired(node, state) && isStaticNode(node); } diff --git a/packages/@lwc/template-compiler/src/codegen/index.ts b/packages/@lwc/template-compiler/src/codegen/index.ts index aeceea3dd0..6c0bf14f11 100644 --- a/packages/@lwc/template-compiler/src/codegen/index.ts +++ b/packages/@lwc/template-compiler/src/codegen/index.ts @@ -16,6 +16,7 @@ import { isStringLiteral, isForBlock, isIf, + isIfBlock, isForEach, isBaseElement, isExpression, @@ -28,6 +29,7 @@ import { isRefDirective, isSpreadDirective, isElement, + isElseifBlock, } from '../shared/ast'; import { TEMPLATE_PARAMS, TEMPLATE_FUNCTION_NAME, RENDERER } from '../shared/constants'; import { @@ -36,6 +38,7 @@ import { ChildNode, Text, If, + IfBlock, ForBlock, ForEach, Attribute, @@ -43,6 +46,7 @@ import { Comment, ForOf, BaseElement, + ElseifBlock, } from '../shared/types'; import * as t from '../shared/estree'; import { @@ -154,11 +158,13 @@ function transform(codeGen: CodeGen): t.Expression { res.push(transformElement(child, slotParentName)); } else if (isComment(child) && codeGen.preserveComments) { res.push(transformComment(child)); + } else if (isIfBlock(child)) { + res.push(transformConditionalParentBlock(child)); } } if (shouldFlatten(codeGen, children)) { - if (children.length === 1 && !containsDynamicChildren(children)) { + if (children.length === 1 && !containsDynamicChildren(parent)) { return res[0]; } else { return codeGen.genFlatten([t.arrayExpression(res)]); @@ -197,6 +203,41 @@ function transform(codeGen: CodeGen): t.Expression { return res; } + /** + * Transforms an IfBlock or ElseifBlock along with both its direct descendants and its 'else' descendants. + * + * @param conditionalParentBlock The IfBlock or ElseifBlock to transform into a conditional expression + * @param key The key to use for this chain of IfBlock/ElseifBlock branches, if applicable + * @returns A conditional expression representing the full conditional tree with conditionalParentBlock as the root node + */ + function transformConditionalParentBlock( + conditionalParentBlock: IfBlock | ElseifBlock, + key?: number + ): t.Expression { + const ifBlockKey = key ?? codeGen.generateKey(); + + const childrenExpression = codeGen.genFragment( + t.literal(ifBlockKey), + transformChildren(conditionalParentBlock) + ); + + let elseExpression: t.Expression = t.literal(null); + if (conditionalParentBlock.else) { + elseExpression = isElseifBlock(conditionalParentBlock.else) + ? transformConditionalParentBlock(conditionalParentBlock.else, ifBlockKey) + : codeGen.genFragment( + t.literal(ifBlockKey), + transformChildren(conditionalParentBlock.else) + ); + } + + return t.conditionalExpression( + codeGen.bindExpression(conditionalParentBlock.condition), + childrenExpression, + elseExpression + ); + } + function applyInlineIf( ifNode: If, node: t.Expression, diff --git a/packages/@lwc/template-compiler/src/parser/index.ts b/packages/@lwc/template-compiler/src/parser/index.ts index 082a11d1ab..56f1ac7d9a 100644 --- a/packages/@lwc/template-compiler/src/parser/index.ts +++ b/packages/@lwc/template-compiler/src/parser/index.ts @@ -30,6 +30,9 @@ import { LWCDirectiveRenderMode, LWCDirectiveDomMode, If, + IfBlock, + ElseBlock, + ElseifBlock, Property, ElementDirectiveName, RootDirectiveName, @@ -253,13 +256,18 @@ function parseElementDirectives( ): ParentNode | undefined { let current: ParentNode | undefined; - const parsers = [parseForEach, parseForOf, parseIf]; + const parsers = [ + parseIfBlock, + parseElseifBlock, + parseElseBlock, + parseForEach, + parseForOf, + parseIf, + ]; for (const parser of parsers) { const prev = current || parent; - const node = parser(ctx, parsedAttr, parse5ElmLocation); + const node = parser(ctx, parsedAttr, parse5ElmLocation, prev); if (node) { - ctx.addNodeCurrentScope(node); - prev.children.push(node); current = node; } } @@ -291,7 +299,7 @@ function parseBaseElement( } if (element) { - ctx.addNodeCurrentScope(element); + ctx.addNodeCurrentElementScope(element); parent.children.push(element); } @@ -306,21 +314,43 @@ function parseChildren( ): void { const children = (parse5Utils.getTemplateContent(parse5Parent) ?? parse5Parent).childNodes; + ctx.beginSiblingScope(); for (const child of children) { ctx.withErrorRecovery(() => { if (parse5Utils.isElementNode(child)) { - ctx.beginScope(); + ctx.beginElementScope(); parseElement(ctx, child, parent, parse5ParentLocation); - ctx.endScope(); + + // If we're parsing a chain of if/elseif/else nodes, any node other than + // an else-if node ends the chain. + const node = ctx.endElementScope(); + if ( + node && + ctx.isParsingSiblingIfBlock() && + !ast.isIfBlock(node) && + !ast.isElseifBlock(node) + ) { + ctx.endIfChain(); + } } else if (parse5Utils.isTextNode(child)) { const textNodes = parseText(ctx, child); parent.children.push(...textNodes); + // Non whitespace text nodes end any if chain we may be parsing + if (ctx.isParsingSiblingIfBlock() && textNodes.length > 0) { + ctx.endIfChain(); + } } else if (parse5Utils.isCommentNode(child)) { const commentNode = parseComment(child); parent.children.push(commentNode); + // If preserveComments is enabled, comments become syntactically meaningful and + // end any if chain we may be parsing + if (ctx.isParsingSiblingIfBlock() && ctx.preserveComments) { + ctx.endIfChain(); + } } }); } + ctx.endSiblingScope(); } function parseText(ctx: ParserCtx, parse5Text: parse5.TextNode): Text[] { @@ -442,13 +472,24 @@ function applyHandlers(ctx: ParserCtx, parsedAttr: ParsedAttribute, element: Bas function parseIf( ctx: ParserCtx, parsedAttr: ParsedAttribute, - parse5ElmLocation: parse5.ElementLocation + parse5ElmLocation: parse5.ElementLocation, + parent: ParentNode ): If | undefined { const ifAttribute = parsedAttr.pick(IF_RE); if (!ifAttribute) { return; } + // if:true cannot be used with lwc:if, lwc:elseif, lwc:else + const incompatibleDirective = ctx.findInCurrentElementScope(ast.isConditionalBlock); + if (incompatibleDirective) { + ctx.throwAtLocation( + ParserDiagnostics.LWC_IF_CANNOT_BE_USED_WITH_IF_DIRECTIVE, + ast.sourceLocation(parse5ElmLocation), + [ifAttribute.name] + ); + } + if (!ast.isExpression(ifAttribute.value)) { ctx.throwOnNode(ParserDiagnostics.IF_DIRECTIVE_SHOULD_BE_EXPRESSION, ifAttribute); } @@ -458,12 +499,167 @@ function parseIf( ctx.throwOnNode(ParserDiagnostics.UNEXPECTED_IF_MODIFIER, ifAttribute, [modifier]); } - return ast.ifNode( + const node = ast.ifNode( modifier, ifAttribute.value, ast.sourceLocation(parse5ElmLocation), ifAttribute.location ); + + ctx.addNodeCurrentElementScope(node); + parent.children.push(node); + + return node; +} + +function parseIfBlock( + ctx: ParserCtx, + parsedAttr: ParsedAttribute, + parse5ElmLocation: parse5.ElementLocation, + parent: ParentNode +): IfBlock | undefined { + const ifBlockAttribute = parsedAttr.pick('lwc:if'); + if (!ifBlockAttribute) { + return; + } + + if (!ast.isExpression(ifBlockAttribute.value)) { + ctx.throwOnNode( + ParserDiagnostics.IF_BLOCK_DIRECTIVE_SHOULD_BE_EXPRESSION, + ifBlockAttribute + ); + } + + // An if block always starts a new chain. + if (ctx.isParsingSiblingIfBlock()) { + ctx.endIfChain(); + } + + const ifNode = ast.ifBlockNode( + ifBlockAttribute.value, + ast.sourceLocation(parse5ElmLocation), + ifBlockAttribute.location + ); + + ctx.addNodeCurrentElementScope(ifNode); + ctx.beginIfChain(ifNode); + parent.children.push(ifNode); + + return ifNode; +} + +function parseElseifBlock( + ctx: ParserCtx, + parsedAttr: ParsedAttribute, + parse5ElmLocation: parse5.ElementLocation, + _: ParentNode +): ElseifBlock | undefined { + const elseifBlockAttribute = parsedAttr.pick('lwc:elseif'); + if (!elseifBlockAttribute) { + return; + } + + const hasIfBlock = ctx.findInCurrentElementScope(ast.isIfBlock); + if (hasIfBlock) { + ctx.throwAtLocation( + ParserDiagnostics.INVALID_IF_BLOCK_DIRECTIVE_WITH_CONDITIONAL, + ast.sourceLocation(parse5ElmLocation), + [elseifBlockAttribute.name] + ); + } + + if (!ast.isExpression(elseifBlockAttribute.value)) { + ctx.throwOnNode( + ParserDiagnostics.ELSEIF_BLOCK_DIRECTIVE_SHOULD_BE_EXPRESSION, + elseifBlockAttribute + ); + } + + const conditionalParent = ctx.getSiblingIfNode(); + if (!conditionalParent || !ast.isConditionalParentBlock(conditionalParent)) { + ctx.throwAtLocation( + ParserDiagnostics.LWC_IF_SCOPE_NOT_FOUND, + ast.sourceLocation(parse5ElmLocation), + [elseifBlockAttribute.name] + ); + } + + const elseifNode = ast.elseifBlockNode( + elseifBlockAttribute.value, + ast.sourceLocation(parse5ElmLocation), + elseifBlockAttribute.location + ); + + // Attach the node as a child of the preceding IfBlock + ctx.addNodeCurrentElementScope(elseifNode); + ctx.appendToIfChain(elseifNode); + conditionalParent.else = elseifNode; + + return elseifNode; +} + +function parseElseBlock( + ctx: ParserCtx, + parsedAttr: ParsedAttribute, + parse5ElmLocation: parse5.ElementLocation, + _: ParentNode +): ElseBlock | undefined { + const elseBlockAttribute = parsedAttr.pick('lwc:else'); + if (!elseBlockAttribute) { + return; + } + + // Cannot be used with lwc:if on the same element + const hasIfBlock = ctx.findInCurrentElementScope(ast.isIfBlock); + if (hasIfBlock) { + ctx.throwAtLocation( + ParserDiagnostics.INVALID_IF_BLOCK_DIRECTIVE_WITH_CONDITIONAL, + ast.sourceLocation(parse5ElmLocation), + [elseBlockAttribute.name] + ); + } + + // Cannot be used with lwc:elseif on the same element + const hasElseifBlock = ctx.findInCurrentElementScope(ast.isElseifBlock); + if (hasElseifBlock) { + ctx.throwAtLocation( + ParserDiagnostics.INVALID_ELSEIF_BLOCK_DIRECTIVE_WITH_CONDITIONAL, + ast.sourceLocation(parse5ElmLocation), + [elseBlockAttribute.name] + ); + } + + // Must be used immediately after an lwc:if or lwc:elseif + const conditionalParent = ctx.getSiblingIfNode(); + if (!conditionalParent || !ast.isConditionalParentBlock(conditionalParent)) { + ctx.throwAtLocation( + ParserDiagnostics.LWC_IF_SCOPE_NOT_FOUND, + ast.sourceLocation(parse5ElmLocation), + [elseBlockAttribute.name] + ); + } + + // Must not have a value + if (!ast.isBooleanLiteral(elseBlockAttribute.value)) { + ctx.throwAtLocation( + ParserDiagnostics.ELSE_BLOCK_DIRECTIVE_CANNOT_HAVE_VALUE, + ast.sourceLocation(parse5ElmLocation) + ); + } + + const elseNode = ast.elseBlockNode( + ast.sourceLocation(parse5ElmLocation), + elseBlockAttribute.location + ); + + // Attach the node as a child of the preceding IfBlock + ctx.addNodeCurrentElementScope(elseNode); + + // Avoid ending the if-chain until we finish parsing all children + ctx.appendToIfChain(elseNode); + conditionalParent.else = elseNode; + + return elseNode; } function applyRootLwcDirectives(ctx: ParserCtx, parsedAttr: ParsedAttribute, root: Root): void { @@ -721,7 +917,8 @@ function applyRefDirective( function parseForEach( ctx: ParserCtx, parsedAttr: ParsedAttribute, - parse5ElmLocation: parse5.ElementLocation + parse5ElmLocation: parse5.ElementLocation, + parent: ParentNode ): ForEach | undefined { const forEachAttribute = parsedAttr.pick('for:each'); const forItemAttribute = parsedAttr.pick('for:item'); @@ -755,13 +952,18 @@ function parseForEach( index = parseIdentifier(ctx, forIndexValue.value, forIndex.location); } - return ast.forEach( + const node = ast.forEach( forEachAttribute.value, ast.sourceLocation(parse5ElmLocation), forEachAttribute.location, item, index ); + + ctx.addNodeCurrentElementScope(node); + parent.children.push(node); + + return node; } else if (forEachAttribute || forItemAttribute) { ctx.throwAtLocation( ParserDiagnostics.FOR_EACH_AND_FOR_ITEM_DIRECTIVES_SHOULD_BE_TOGETHER, @@ -773,14 +975,15 @@ function parseForEach( function parseForOf( ctx: ParserCtx, parsedAttr: ParsedAttribute, - parse5ElmLocation: parse5.ElementLocation + parse5ElmLocation: parse5.ElementLocation, + parent: ParentNode ): ForOf | undefined { const iteratorExpression = parsedAttr.pick(ITERATOR_RE); if (!iteratorExpression) { return; } - const hasForEach = ctx.findSibling(ast.isForEach); + const hasForEach = ctx.findInCurrentElementScope(ast.isForEach); if (hasForEach) { ctx.throwAtLocation( ParserDiagnostics.INVALID_FOR_EACH_WITH_ITERATOR, @@ -800,12 +1003,17 @@ function parseForOf( const iterator = parseIdentifier(ctx, iteratorName, iteratorExpression.location); - return ast.forOf( + const node = ast.forOf( iteratorExpression.value, iterator, ast.sourceLocation(parse5ElmLocation), iteratorExpression.location ); + + ctx.addNodeCurrentElementScope(node); + parent.children.push(node); + + return node; } function applyKey(ctx: ParserCtx, parsedAttr: ParsedAttribute, element: BaseElement): void { @@ -856,7 +1064,7 @@ function parseSlot( ): Slot { const location = ast.sourceLocation(parse5ElmLocation); - const hasDirectives = ctx.findSibling(ast.isForBlock) || ctx.findSibling(ast.isIf); + const hasDirectives = ctx.findInCurrentElementScope(ast.isElementDirective); if (hasDirectives) { ctx.throwAtLocation(ParserDiagnostics.SLOT_TAG_CANNOT_HAVE_DIRECTIVES, location); } @@ -897,8 +1105,8 @@ function parseSlot( } } - const alreadySeen = ctx.seenSlots.has(name); - ctx.seenSlots.add(name); + const alreadySeen = ctx.hasSeenSlot(name); + ctx.addSeenSlot(name); if (alreadySeen) { ctx.warnAtLocation(ParserDiagnostics.NO_DUPLICATE_SLOTS, location, [ diff --git a/packages/@lwc/template-compiler/src/parser/parser.ts b/packages/@lwc/template-compiler/src/parser/parser.ts index 81dfc05b5c..545f5d3a48 100644 --- a/packages/@lwc/template-compiler/src/parser/parser.ts +++ b/packages/@lwc/template-compiler/src/parser/parser.ts @@ -22,6 +22,9 @@ import { ParentNode, BaseNode, LWCDirectiveRenderMode, + IfBlock, + ElseifBlock, + ElseBlock, } from '../shared/types'; function normalizeLocation(location?: SourceLocation): Location { @@ -45,6 +48,30 @@ interface ParentWrapper { current: ParentNode; } +interface IfContext { + currentNode: IfBlock | ElseifBlock | ElseBlock; + + // Within a specific if-context, each set of seen slot names must be tracked separately + // because duplicate names in separate branches of the same if-block are allowed (the branching + // logic provides a compile-time guarantee that the slots will not be rendered multiple times). + // seenSlots keeps track of each set holding the slots seen in each branch of the if-block. + seenSlots: Set[]; +} + +// A SiblingScope object keeps track of the context needed to parse a series of if-elseif-else nodes. +interface SiblingScope { + // Context for the if-elseif-else chain currently being parsed at this level. This + // IfContext keeps track of the most recently parsed node in the chain and the set of slot names we've seen in all + // previous siblings in the chain. + ifContext?: IfContext; + + // Reference to the nearest ancestor IfContext. The existence of an ancestor + // IfContext means that we are currently parsing nodes nested within an if-elseif-else chain. Context from that ancestor + // is needed to track which slot names have already been seen in and only in the current scope. This reference is also needed + // so we know where to merge all visited slot names from the current IfContext. + ancestorIfContext?: IfContext; +} + export default class ParserCtx { private readonly source: String; @@ -55,17 +82,23 @@ export default class ParserCtx { readonly seenSlots: Set = new Set(); /** - * Scopes keep track of the hierarchy of ParentNodes as the parser traverses the parse5 AST. - * Each scope is represented by an array where each node in the array correspond to either - * a ForEach, ForOf, If, Element, Component, or Slot. + * 'elementScopes' keeps track of the hierarchy of ParentNodes as the parser + * traverses the parse5 AST. Each 'elementScope' is an array where each node in + * the array corresponds to either an IfBlock, ElseifBlock, ElseBlock, ForEach, ForOf, If, Element, Component, or Slot. * - * Currently, each scope has a hierarchy of ForBlock > IfBlock > Element | Component | Slot. - * Note: Not all scopes will have all three, but when they do, they will appear in this order. + * Currently, each elementScope has a hierarchy of IfBlock > ForBlock > If > Element | Component | Slot. + * Note: Not all elementScopes will have all the nodes listed above, but when they do, they will appear in this order. * We do not keep track of template nodes. * * Each scope corresponds to the original parse5.Element node. */ - private readonly scopes: ParentNode[][] = []; + private readonly elementScopes: ParentNode[][] = []; + + /** + * 'siblingScopes' keeps track of the context from one sibling node to another. + * This holds the info needed to properly parse lwc:if, lwc:elseif, and lwc:else directives. + */ + private readonly siblingScopes: SiblingScope[] = []; renderMode: LWCDirectiveRenderMode; preserveComments: boolean; @@ -92,7 +125,7 @@ export default class ParserCtx { * This method flattens the scopes into a single array for traversal. */ *ancestors(element?: ParentNode): IterableIterator { - const ancestors = ([] as ParentNode[]).concat(...this.scopes); + const ancestors = this.elementScopes.flat(); const start = element ? ancestors.indexOf(element) : ancestors.length - 1; for (let i = start; i >= 0; i--) { @@ -134,33 +167,138 @@ export default class ParserCtx { * @param {function} predicate - This callback is called once for each sibling in the current scope * until it finds one where predicate returns true. */ - findSibling(predicate: (node: ParentNode) => node is A): A | null { - const currentScope = this.currentScope() || []; - const sibling = currentScope.find(predicate); - return sibling || null; + findInCurrentElementScope( + predicate: (node: ParentNode) => node is A + ): A | null { + const currentScope = this.currentElementScope() || []; + return currentScope.find(predicate) || null; } - beginScope(): void { - this.scopes.push([]); + beginElementScope(): void { + this.elementScopes.push([]); } - endScope(): void { - this.scopes.pop(); + endElementScope(): ParentNode | undefined { + const scope = this.elementScopes.pop(); + return scope ? scope[0] : undefined; } - addNodeCurrentScope(node: ParentNode): void { - const currentScope = this.currentScope(); + addNodeCurrentElementScope(node: ParentNode): void { + const currentScope = this.currentElementScope(); /* istanbul ignore if */ if (!currentScope) { - throw new Error("Can't invoke addNodeCurrentScope if there is no current scope"); + throw new Error("Can't invoke addNodeCurrentElementScope if there is no current scope"); } currentScope.push(node); } - private currentScope(): ParentNode[] | undefined { - return this.scopes[this.scopes.length - 1]; + hasSeenSlot(name: string): boolean { + return this.seenSlotsFromAncestorIfTree().has(name); + } + + addSeenSlot(name: string): void { + const currentSeenSlots = this.seenSlotsFromAncestorIfTree(); + if (currentSeenSlots) { + currentSeenSlots.add(name); + } else { + this.seenSlots.add(name); + } + } + + private currentElementScope(): ParentNode[] | undefined { + return this.elementScopes[this.elementScopes.length - 1]; + } + + beginSiblingScope() { + this.siblingScopes.push({ + ancestorIfContext: this.currentIfContext() || this.ancestorIfContext(), + }); + } + + endSiblingScope() { + this.siblingScopes.pop(); + } + + beginIfChain(node: IfBlock) { + const currentSiblingContext = this.currentSiblingContext(); + if (!currentSiblingContext) { + throw new Error('Cannot invoke beginIfChain if there is currently no sibling context'); + } + + const currentIfContext = this.currentIfContext(); + if (currentIfContext) { + throw new Error( + 'Should not invoke beginIfChain if an if context already exists. First end the current chain before starting a new one.' + ); + } + + const previouslySeenSlots = this.seenSlotsFromAncestorIfTree(); + currentSiblingContext.ifContext = { + currentNode: node, + seenSlots: [new Set(previouslySeenSlots)], + }; + } + + appendToIfChain(node: ElseifBlock | ElseBlock) { + const currentIfContext = this.currentIfContext(); + if (!currentIfContext) { + throw new Error('Cannot invoke appendToIfChain without first setting the if context.'); + } + + currentIfContext.currentNode = node; + + const previouslySeenSlots = this.seenSlotsFromAncestorIfTree(); + currentIfContext.seenSlots.push(new Set(previouslySeenSlots)); + } + + endIfChain() { + const currentIfContext = this.currentIfContext(); + if (!currentIfContext) { + throw new Error('Cannot invoke endIfChain if there is currently no if context'); + } + + // Merge seen slot names from the current if chain into the parent scope. + const seenSlotsInAncestorIfTree = this.seenSlotsFromAncestorIfTree(); + for (const seenSlots of currentIfContext.seenSlots) { + for (const name of seenSlots) { + seenSlotsInAncestorIfTree.add(name); + } + } + + const currentSiblingContext = this.currentSiblingContext(); + if (currentSiblingContext) { + currentSiblingContext.ifContext = undefined; + } + } + + getSiblingIfNode(): IfBlock | ElseifBlock | ElseBlock | undefined { + return this.currentIfContext()?.currentNode; + } + + isParsingSiblingIfBlock(): boolean { + return !!this.currentIfContext(); + } + + private currentSiblingContext(): SiblingScope | undefined { + return this.siblingScopes[this.siblingScopes.length - 1]; + } + + private currentIfContext(): IfContext | undefined { + return this.currentSiblingContext()?.ifContext; + } + + private ancestorIfContext(): IfContext | undefined { + return this.currentSiblingContext()?.ancestorIfContext; + } + + private seenSlotsFromAncestorIfTree(): Set { + const ancestorIfContext = this.ancestorIfContext(); + if (ancestorIfContext) { + return ancestorIfContext.seenSlots[ancestorIfContext.seenSlots.length - 1]; + } + return this.seenSlots; } /** diff --git a/packages/@lwc/template-compiler/src/shared/ast.ts b/packages/@lwc/template-compiler/src/shared/ast.ts index 118e567619..aff748411c 100644 --- a/packages/@lwc/template-compiler/src/shared/ast.ts +++ b/packages/@lwc/template-compiler/src/shared/ast.ts @@ -33,6 +33,9 @@ import { ForOf, LWCDirectiveRenderMode, If, + IfBlock, + ElseBlock, + ElseifBlock, ElementSourceLocation, InnerHTMLDirective, BaseElement, @@ -205,6 +208,46 @@ export function ifNode( }; } +export function ifBlockNode( + condition: Expression, + elementLocation: SourceLocation, + directiveLocation: SourceLocation +): IfBlock { + return { + type: 'IfBlock', + condition, + location: elementLocation, + directiveLocation, + children: [], + }; +} + +export function elseifBlockNode( + condition: Expression, + elementLocation: SourceLocation, + directiveLocation: SourceLocation +): ElseifBlock { + return { + type: 'ElseifBlock', + condition, + location: elementLocation, + directiveLocation, + children: [], + }; +} + +export function elseBlockNode( + elementLocation: SourceLocation, + directiveLocation: SourceLocation +): ElseBlock { + return { + type: 'ElseBlock', + location: elementLocation, + directiveLocation, + children: [], + }; +} + export function eventListener( name: string, handler: Expression, @@ -386,6 +429,32 @@ export function isIf(node: BaseNode): node is If { return node.type === 'If'; } +export function isIfBlock(node: BaseNode): node is IfBlock { + return node.type === 'IfBlock'; +} + +export function isElseifBlock(node: BaseNode): node is ElseifBlock { + return node.type === 'ElseifBlock'; +} + +export function isElseBlock(node: BaseNode): node is ElseBlock { + return node.type === 'ElseBlock'; +} + +export function isConditionalParentBlock(node: BaseNode): node is IfBlock | ElseifBlock { + return isIfBlock(node) || isElseifBlock(node); +} + +export function isConditionalBlock(node: BaseNode): node is IfBlock | ElseifBlock | ElseBlock { + return isIfBlock(node) || isElseifBlock(node) || isElseBlock(node); +} + +export function isElementDirective( + node: BaseNode +): node is IfBlock | ElseifBlock | ElseBlock | ForBlock | If { + return isConditionalBlock(node) || isForBlock(node) || isIf(node); +} + export function isParentNode(node: BaseNode): node is ParentNode { return isBaseElement(node) || isRoot(node) || isForBlock(node) || isIf(node); } diff --git a/packages/@lwc/template-compiler/src/shared/types.ts b/packages/@lwc/template-compiler/src/shared/types.ts index 57c2f5c6f8..c97baae7c3 100644 --- a/packages/@lwc/template-compiler/src/shared/types.ts +++ b/packages/@lwc/template-compiler/src/shared/types.ts @@ -182,12 +182,40 @@ interface DirectiveParentNode extends BaseParentNode { directiveLocation: SourceLocation; } +/** + * Node representing the if:true and if:false directives + */ export interface If extends DirectiveParentNode { type: 'If'; modifier: string; condition: Expression; } +/** + * Node representing the lwc:if directive + */ +export interface IfBlock extends DirectiveParentNode { + type: 'IfBlock'; + condition: Expression; + else?: ElseifBlock | ElseBlock; +} + +/** + * Node representing the lwc:elseif directive + */ +export interface ElseifBlock extends DirectiveParentNode { + type: 'ElseifBlock'; + condition: Expression; + else?: ElseifBlock | ElseBlock; +} + +/** + * Node representing the lwc:else directive + */ +export interface ElseBlock extends DirectiveParentNode { + type: 'ElseBlock'; +} + export interface ForEach extends DirectiveParentNode { type: 'ForEach'; expression: Expression; @@ -203,11 +231,28 @@ export interface ForOf extends DirectiveParentNode { export type ForBlock = ForEach | ForOf; -export type ParentNode = Root | ForBlock | If | BaseElement; - -export type ChildNode = ForBlock | If | BaseElement | Comment | Text; - -export type Node = Root | ForBlock | If | BaseElement | Comment | Text; +export type ParentNode = Root | ForBlock | If | IfBlock | ElseifBlock | ElseBlock | BaseElement; + +export type ChildNode = + | ForBlock + | If + | IfBlock + | ElseifBlock + | ElseBlock + | BaseElement + | Comment + | Text; + +export type Node = + | Root + | ForBlock + | If + | IfBlock + | ElseifBlock + | ElseBlock + | BaseElement + | Comment + | Text; export enum ElementDirectiveName { Dom = 'lwc:dom',