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 50cd4849d9..820ba0caf0 100644 --- a/packages/@lwc/errors/src/compiler/error-info/template-transform.ts +++ b/packages/@lwc/errors/src/compiler/error-info/template-transform.ts @@ -393,6 +393,7 @@ export const ParserDiagnostics = { url: '', }, + // TODO [#3100]: Update message to point to external documentation once available. SLOT_TAG_CANNOT_HAVE_DIRECTIVES: { code: 1082, message: diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures.spec.ts b/packages/@lwc/template-compiler/src/__tests__/fixtures.spec.ts index f086154725..53b7a0c07d 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures.spec.ts +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures.spec.ts @@ -15,7 +15,7 @@ import compiler, { Config } from '../index'; describe('fixtures', () => { testFixtureDir( { - root: path.resolve(__dirname, 'fixtures'), + root: path.resolve(__dirname, 'fixtures', 'scoped-slots'), pattern: '**/actual.html', }, ({ src, dirname }) => { diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/actual.html new file mode 100644 index 0000000000..2866bfca00 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/actual.html @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/config.json new file mode 100644 index 0000000000..089a290bd4 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/config.json @@ -0,0 +1,3 @@ +{ + "enableScopedSlots": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/metadata.json new file mode 100644 index 0000000000..739a11a207 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-after/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1172, + "message": "LWC1172: Invalid duplicate scoped slots (default)", + "level": 1, + "location": { + "line": 11, + "column": 5, + "start": 320, + "length": 46 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/actual.html new file mode 100644 index 0000000000..1dc62bc404 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/actual.html @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/config.json new file mode 100644 index 0000000000..089a290bd4 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/config.json @@ -0,0 +1,3 @@ +{ + "enableScopedSlots": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/metadata.json new file mode 100644 index 0000000000..3c743fc6e4 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-default-slot-before/metadata.json @@ -0,0 +1,26 @@ +{ + "warnings": [ + { + "code": 1173, + "message": "LWC1173: Mixing slot types disallowed for same (default) slot.", + "level": 1, + "location": { + "line": 4, + "column": 9, + "start": 131, + "length": 13 + } + }, + { + "code": 1172, + "message": "LWC1172: Invalid duplicate scoped slots (default)", + "level": 1, + "location": { + "line": 7, + "column": 9, + "start": 209, + "length": 46 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/actual.html new file mode 100644 index 0000000000..e21da8728b --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/actual.html @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/config.json new file mode 100644 index 0000000000..089a290bd4 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/config.json @@ -0,0 +1,3 @@ +{ + "enableScopedSlots": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/metadata.json new file mode 100644 index 0000000000..1732d6dcda --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/invalid/duplicate-named-slot-after/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1172, + "message": "LWC1172: Invalid duplicate scoped slots (name=\"slotname1\")", + "level": 1, + "location": { + "line": 8, + "column": 5, + "start": 243, + "length": 63 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/actual.html new file mode 100644 index 0000000000..b3f875496c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/actual.html @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/ast.json new file mode 100644 index 0000000000..6688af5f91 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/ast.json @@ -0,0 +1,250 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 8, + "endColumn": 12, + "start": 0, + "end": 266, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 35, + "start": 0, + "end": 34 + }, + "endTag": { + "startLine": 8, + "startColumn": 1, + "endLine": 8, + "endColumn": 12, + "start": 255, + "end": 266 + } + }, + "directives": [ + { + "type": "Directive", + "name": "RenderMode", + "value": { + "type": "Literal", + "value": "light" + }, + "location": { + "startLine": 1, + "startColumn": 11, + "endLine": 1, + "endColumn": 34, + "start": 10, + "end": 33 + } + } + ], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 13, + "name": "showStandard", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 36, + "start": 49, + "end": 70 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 4, + "endColumn": 16, + "start": 39, + "end": 126 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 36, + "start": 49, + "end": 70 + }, + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "slotname1", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 39, + "start": 80, + "end": 110, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 32, + "start": 80, + "end": 103 + }, + "endTag": { + "startLine": 3, + "startColumn": 32, + "endLine": 3, + "endColumn": 39, + "start": 103, + "end": 110 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "slotname1" + }, + "location": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 31, + "start": 86, + "end": 102 + } + } + ], + "properties": [], + "directives": [], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 12, + "name": "showVariant", + "location": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 39, + "start": 141, + "end": 165 + } + }, + "location": { + "startLine": 5, + "startColumn": 5, + "endLine": 7, + "endColumn": 16, + "start": 131, + "end": 254 + }, + "directiveLocation": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 39, + "start": 141, + "end": 165 + }, + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "slotname1", + "location": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 72, + "start": 175, + "end": 238, + "startTag": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 65, + "start": 175, + "end": 231 + }, + "endTag": { + "startLine": 6, + "startColumn": 65, + "endLine": 6, + "endColumn": 72, + "start": 231, + "end": 238 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "slotname1" + }, + "location": { + "startLine": 6, + "startColumn": 15, + "endLine": 6, + "endColumn": 31, + "start": 181, + "end": 197 + } + } + ], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "SlotBind", + "value": { + "type": "Identifier", + "start": 1, + "end": 17, + "name": "slot1VariantData", + "location": { + "startLine": 6, + "startColumn": 32, + "endLine": 6, + "endColumn": 64, + "start": 198, + "end": 230 + } + }, + "location": { + "startLine": 6, + "startColumn": 32, + "endLine": 6, + "endColumn": 64, + "start": 198, + "end": 230 + } + } + ], + "listeners": [], + "children": [] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/config.json new file mode 100644 index 0000000000..089a290bd4 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/config.json @@ -0,0 +1,3 @@ +{ + "enableScopedSlots": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/expected.js new file mode 100644 index 0000000000..32f3808673 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/expected.js @@ -0,0 +1,39 @@ +import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + name: "slotname1", + }, + key: 1, +}; +const stc1 = []; +const stc2 = { + name: "slotname1", +}; +function tmpl($api, $cmp, $slotset, $ctx) { + const { s: api_slot, fr: api_fragment } = $api; + return [ + $cmp.showStandard + ? api_fragment(0, api_slot("slotname1", stc0, stc1, $slotset), 0) + : $cmp.showVariant + ? api_fragment( + 0, + api_slot( + "slotname1", + { + attrs: stc2, + key: 2, + slotData: $cmp.slot1VariantData, + }, + stc1, + $slotset + ), + 0 + ) + : null, + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.slots = ["slotname1"]; +tmpl.stylesheets = []; +tmpl.renderMode = "light"; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/mixed-slot-types/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/actual.html new file mode 100644 index 0000000000..5d97bdb0fe --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/actual.html @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/ast.json new file mode 100644 index 0000000000..7751261dc1 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/ast.json @@ -0,0 +1,277 @@ +{ + "root": { + "type": "Root", + "location": { + "startLine": 1, + "startColumn": 1, + "endLine": 8, + "endColumn": 12, + "start": 0, + "end": 299, + "startTag": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 35, + "start": 0, + "end": 34 + }, + "endTag": { + "startLine": 8, + "startColumn": 1, + "endLine": 8, + "endColumn": 12, + "start": 288, + "end": 299 + } + }, + "directives": [ + { + "type": "Directive", + "name": "RenderMode", + "value": { + "type": "Literal", + "value": "light" + }, + "location": { + "startLine": 1, + "startColumn": 11, + "endLine": 1, + "endColumn": 34, + "start": 10, + "end": 33 + } + } + ], + "children": [ + { + "type": "IfBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 13, + "name": "showStandard", + "location": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 36, + "start": 49, + "end": 70 + } + }, + "location": { + "startLine": 2, + "startColumn": 5, + "endLine": 4, + "endColumn": 16, + "start": 39, + "end": 159 + }, + "directiveLocation": { + "startLine": 2, + "startColumn": 15, + "endLine": 2, + "endColumn": 36, + "start": 49, + "end": 70 + }, + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "slotname1", + "location": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 72, + "start": 80, + "end": 143, + "startTag": { + "startLine": 3, + "startColumn": 9, + "endLine": 3, + "endColumn": 65, + "start": 80, + "end": 136 + }, + "endTag": { + "startLine": 3, + "startColumn": 65, + "endLine": 3, + "endColumn": 72, + "start": 136, + "end": 143 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "slotname1" + }, + "location": { + "startLine": 3, + "startColumn": 15, + "endLine": 3, + "endColumn": 31, + "start": 86, + "end": 102 + } + } + ], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "SlotBind", + "value": { + "type": "Identifier", + "start": 1, + "end": 17, + "name": "slot1VariantData", + "location": { + "startLine": 3, + "startColumn": 32, + "endLine": 3, + "endColumn": 64, + "start": 103, + "end": 135 + } + }, + "location": { + "startLine": 3, + "startColumn": 32, + "endLine": 3, + "endColumn": 64, + "start": 103, + "end": 135 + } + } + ], + "listeners": [], + "children": [] + } + ], + "else": { + "type": "ElseifBlock", + "condition": { + "type": "Identifier", + "start": 1, + "end": 12, + "name": "showVariant", + "location": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 39, + "start": 174, + "end": 198 + } + }, + "location": { + "startLine": 5, + "startColumn": 5, + "endLine": 7, + "endColumn": 16, + "start": 164, + "end": 287 + }, + "directiveLocation": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 39, + "start": 174, + "end": 198 + }, + "children": [ + { + "type": "Slot", + "name": "slot", + "namespace": "http://www.w3.org/1999/xhtml", + "slotName": "slotname1", + "location": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 72, + "start": 208, + "end": 271, + "startTag": { + "startLine": 6, + "startColumn": 9, + "endLine": 6, + "endColumn": 65, + "start": 208, + "end": 264 + }, + "endTag": { + "startLine": 6, + "startColumn": 65, + "endLine": 6, + "endColumn": 72, + "start": 264, + "end": 271 + } + }, + "attributes": [ + { + "type": "Attribute", + "name": "name", + "value": { + "type": "Literal", + "value": "slotname1" + }, + "location": { + "startLine": 6, + "startColumn": 15, + "endLine": 6, + "endColumn": 31, + "start": 214, + "end": 230 + } + } + ], + "properties": [], + "directives": [ + { + "type": "Directive", + "name": "SlotBind", + "value": { + "type": "Identifier", + "start": 1, + "end": 17, + "name": "slot1VariantData", + "location": { + "startLine": 6, + "startColumn": 32, + "endLine": 6, + "endColumn": 64, + "start": 231, + "end": 263 + } + }, + "location": { + "startLine": 6, + "startColumn": 32, + "endLine": 6, + "endColumn": 64, + "start": 231, + "end": 263 + } + } + ], + "listeners": [], + "children": [] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/config.json new file mode 100644 index 0000000000..089a290bd4 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/config.json @@ -0,0 +1,3 @@ +{ + "enableScopedSlots": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/expected.js new file mode 100644 index 0000000000..ff7c34287a --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/expected.js @@ -0,0 +1,46 @@ +import { registerTemplate } from "lwc"; +const stc0 = { + name: "slotname1", +}; +const stc1 = []; +function tmpl($api, $cmp, $slotset, $ctx) { + const { s: api_slot, fr: api_fragment } = $api; + return [ + $cmp.showStandard + ? api_fragment( + 0, + api_slot( + "slotname1", + { + attrs: stc0, + key: 1, + slotData: $cmp.slot1VariantData, + }, + stc1, + $slotset + ), + 0 + ) + : $cmp.showVariant + ? api_fragment( + 0, + api_slot( + "slotname1", + { + attrs: stc0, + key: 2, + slotData: $cmp.slot1VariantData, + }, + stc1, + $slotset + ), + 0 + ) + : null, + ]; + /*LWC compiler vX.X.X*/ +} +export default registerTemplate(tmpl); +tmpl.slots = ["slotname1"]; +tmpl.stylesheets = []; +tmpl.renderMode = "light"; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/metadata.json new file mode 100644 index 0000000000..51ec5f799c --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/if-block/valid/same-slot-types/metadata.json @@ -0,0 +1,3 @@ +{ + "warnings": [] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/actual.html b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/actual.html new file mode 100644 index 0000000000..5c9248dce2 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/actual.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/ast.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/ast.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/ast.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/config.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/config.json new file mode 100644 index 0000000000..089a290bd4 --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/config.json @@ -0,0 +1,3 @@ +{ + "enableScopedSlots": true +} diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/expected.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/metadata.json b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/metadata.json new file mode 100644 index 0000000000..ff3294afac --- /dev/null +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/scoped-slots/invalid/slot-bind/mixed-slot-alt/metadata.json @@ -0,0 +1,15 @@ +{ + "warnings": [ + { + "code": 1173, + "message": "LWC1173: Mixing slot types disallowed for same (default) slot.", + "level": 1, + "location": { + "line": 3, + "column": 5, + "start": 69, + "length": 49 + } + } + ] +} \ No newline at end of file diff --git a/packages/@lwc/template-compiler/src/codegen/codegen.ts b/packages/@lwc/template-compiler/src/codegen/codegen.ts index 4a17204c89..72b767c9a1 100644 --- a/packages/@lwc/template-compiler/src/codegen/codegen.ts +++ b/packages/@lwc/template-compiler/src/codegen/codegen.ts @@ -258,6 +258,9 @@ export default class CodeGen { return this._renderApiCall(RENDER_APIS.scopedFragId, [id]); } + /** + * Generates childs vnodes when slot content is static. + */ getSlot(slotName: string, data: t.ObjectExpression, children: t.Expression) { this.slotNames.add(slotName); @@ -269,6 +272,13 @@ export default class CodeGen { ]); } + /** + * Generates a factory function that inturn generates child vnodes for scoped slot content. + */ + getScopedSlotFactory(callback: t.FunctionExpression, slotName: t.SimpleLiteral) { + return this._renderApiCall(RENDER_APIS.scopedSlotFactory, [callback, slotName]); + } + genTabIndex(children: [t.Expression]) { return this._renderApiCall(RENDER_APIS.tabindex, children); } @@ -358,10 +368,6 @@ export default class CodeGen { ); } - getScopedSlotFactory(callback: t.FunctionExpression, slotName: t.SimpleLiteral) { - return this._renderApiCall(RENDER_APIS.scopedSlotFactory, [callback, slotName]); - } - private _renderApiCall( primitive: RenderPrimitiveDefinition, params: t.Expression[] diff --git a/packages/@lwc/template-compiler/src/parser/index.ts b/packages/@lwc/template-compiler/src/parser/index.ts index 56f9f2c184..2237a89e8f 100644 --- a/packages/@lwc/template-compiler/src/parser/index.ts +++ b/packages/@lwc/template-compiler/src/parser/index.ts @@ -1219,21 +1219,24 @@ function parseSlot( ctx.addSeenSlot(name); if (alreadySeen) { - // If slot name has been shared with a prior scoped slot, throw an error. // Scoped slots do not allow duplicate or mixed slots // https://rfcs.lwc.dev/rfcs/lwc/0118-scoped-slots-light-dom#restricting-ambigious-bindings // https://rfcs.lwc.dev/rfcs/lwc/0118-scoped-slots-light-dom#invalid-usages + // Note: ctx.seenScopedSlots is not "if" context aware and it does not need to be. + // It is only responsible to determine if a scoped slot with the same name has been seen prior. if (ctx.seenScopedSlots.has(name)) { // Differentiate between mixed type or duplicate scoped slot const errorInfo = isScopedSlot - ? ParserDiagnostics.NO_DUPLICATE_SCOPED_SLOT - : ParserDiagnostics.NO_MIXED_SLOT_TYPES; + ? ParserDiagnostics.NO_DUPLICATE_SCOPED_SLOT // error + : ParserDiagnostics.NO_MIXED_SLOT_TYPES; // error ctx.throwAtLocation(errorInfo, location, [name === '' ? 'default' : `name="${name}"`]); } else { + // Differentiate between mixed type or duplicate standard slot + const errorInfo = isScopedSlot + ? ParserDiagnostics.NO_MIXED_SLOT_TYPES // error + : ParserDiagnostics.NO_DUPLICATE_SLOTS; // warning // for standard slots, preserve old behavior of warnings - ctx.warnAtLocation(ParserDiagnostics.NO_DUPLICATE_SLOTS, location, [ - name === '' ? 'default' : `name="${name}"`, - ]); + ctx.warnAtLocation(errorInfo, location, [name === '' ? 'default' : `name="${name}"`]); } } else if (!isScopedSlot && isInIteration(ctx)) { // Scoped slots are allowed to be placed in iteration blocks diff --git a/packages/@lwc/template-compiler/src/parser/parser.ts b/packages/@lwc/template-compiler/src/parser/parser.ts index a07d6386cb..1229bac892 100644 --- a/packages/@lwc/template-compiler/src/parser/parser.ts +++ b/packages/@lwc/template-compiler/src/parser/parser.ts @@ -80,6 +80,9 @@ export default class ParserCtx { readonly seenIds: Set = new Set(); readonly seenSlots: Set = new Set(); + /** + * This set is not aware of if-elseif-else blocks. + */ readonly seenScopedSlots: Set = new Set(); /** diff --git a/packages/@lwc/template-compiler/src/shared/ast.ts b/packages/@lwc/template-compiler/src/shared/ast.ts index 2fe6e75c11..d9af63fd35 100644 --- a/packages/@lwc/template-compiler/src/shared/ast.ts +++ b/packages/@lwc/template-compiler/src/shared/ast.ts @@ -45,7 +45,6 @@ import { ElementDirective, RootDirective, SlotBindDirective, - /* SlotDataDirective, */ ScopedSlotContent, SlotDataDirective, } from './types'; diff --git a/scripts/bundlesize/bundlesize.config.json b/scripts/bundlesize/bundlesize.config.json index c5cafa216e..d696800e7f 100644 --- a/scripts/bundlesize/bundlesize.config.json +++ b/scripts/bundlesize/bundlesize.config.json @@ -2,7 +2,7 @@ "files": [ { "path": "packages/lwc/dist/engine-dom/umd/es2017/engine-dom.min.js", - "maxSize": "18.6KB", + "maxSize": "20KB", "compression": "gzip" }, {