-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
support <elem slot=...> in slots forwarding
- Loading branch information
Showing
17 changed files
with
253 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
src/compiler/compile/nodes/extract_children_to_slot_templates.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import { x } from 'code-red'; | ||
import { TemplateNode } from '../../interfaces'; | ||
import { regex_only_whitespaces } from '../../utils/patterns'; | ||
import compiler_errors from '../compiler_errors'; | ||
import Component from '../Component'; | ||
|
||
export function extract_children_to_slot_templates(component: Component, node: TemplateNode, extract_default_slot: boolean) { | ||
const result = []; | ||
for (let i = node.children.length - 1; i >= 0; i--) { | ||
const child = node.children[i]; | ||
if (child.type === 'SlotTemplate') { | ||
result.push(child); | ||
node.children.splice(i, 1); | ||
} else if ((child.type === 'Element' || child.type === 'InlineComponent' || child.type === 'Slot') && child.attributes.find(attribute => attribute.name === 'slot')) { | ||
let slot_template = { | ||
start: child.start, | ||
end: child.end, | ||
type: 'SlotTemplate', | ||
name: 'svelte:fragment', | ||
attributes: [], | ||
children: [child] | ||
}; | ||
|
||
// transfer attributes | ||
for (let i = child.attributes.length - 1; i >= 0; i--) { | ||
const attribute = child.attributes[i]; | ||
if (attribute.type === 'Let') { | ||
slot_template.attributes.push(attribute); | ||
child.attributes.splice(i, 1); | ||
} else if (attribute.type === 'Attribute' && attribute.name === 'slot') { | ||
slot_template.attributes.push(attribute); | ||
} | ||
} | ||
// transfer const | ||
for (let i = child.children.length - 1; i >= 0; i--) { | ||
const child_child = child.children[i]; | ||
if (child_child.type === 'ConstTag') { | ||
slot_template.children.push(child_child); | ||
child.children.splice(i, 1); | ||
} | ||
} | ||
|
||
// if the <slot slot="x"> does not have any fallback | ||
// then we make <slot slot="x" name="b" /> | ||
// into {#if $$slots.x}<slot slot="x" name="b" />{/if} | ||
// this makes the slots forwarding to passthrough | ||
if (child.type === 'Slot' && child.children.length === 0) { | ||
const slot_template_name = child.attributes.find(attribute => attribute.name === 'name')?.value[0].data ?? 'default'; | ||
slot_template = { | ||
start: slot_template.start, | ||
end: slot_template.end, | ||
type: 'SlotTemplateIfBlock', | ||
expression: x`$$slots.${slot_template_name}`, | ||
children: [slot_template] | ||
} as any; | ||
} | ||
|
||
result.push(slot_template); | ||
node.children.splice(i, 1); | ||
} else if (child.type === 'Comment' && result.length > 0) { | ||
result[result.length - 1].children.unshift(child); | ||
node.children.splice(i, 1); | ||
} else if (child.type === 'Text' && regex_only_whitespaces.test(child.data)) { | ||
// ignore | ||
} else if (child.type === 'ConstTag') { | ||
if (!extract_default_slot) { | ||
result.push(child); | ||
} | ||
} else if (child.type === 'IfBlock' && if_block_contains_slot_template(child)) { | ||
result.push({ | ||
...child, | ||
type: 'SlotTemplateIfBlock' | ||
}); | ||
node.children.splice(i, 1); | ||
} else if (!extract_default_slot) { | ||
component.error(child, compiler_errors.invalid_mix_element_and_conditional_slot); | ||
} | ||
} | ||
|
||
if (extract_default_slot) { | ||
if (node.children.some(node => not_whitespace_text(node))) { | ||
result.push({ | ||
start: node.start, | ||
end: node.end, | ||
type: 'SlotTemplate', | ||
name: 'svelte:fragment', | ||
attributes: [], | ||
children: node.children | ||
}); | ||
} | ||
} | ||
return result.reverse(); | ||
} | ||
|
||
|
||
function not_whitespace_text(node) { | ||
return !(node.type === 'Text' && regex_only_whitespaces.test(node.data)); | ||
} | ||
|
||
function if_block_contains_slot_template(node: TemplateNode) { | ||
for (const child of node.children) { | ||
if (child.type === 'SlotTemplate') return true; | ||
if (child.type === 'IfBlock' && if_block_contains_slot_template(child)) return true; | ||
if ((child.type === 'Element' || child.type === 'InlineComponent' || child.type === 'Slot') && child.attributes.find(attribute => attribute.name === 'slot')) return true; | ||
} | ||
return false; | ||
} |
3 changes: 3 additions & 0 deletions
3
test/runtime/samples/component-conditional-slot-11-slot-attribute/Foo.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<slot name="a">default a</slot> | ||
<hr/> | ||
<slot name="b">default b</slot> |
15 changes: 15 additions & 0 deletions
15
test/runtime/samples/component-conditional-slot-11-slot-attribute/_config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export default { | ||
html: ` | ||
default a | ||
<hr> | ||
<div slot="b">hello b</div> | ||
`, | ||
test({ assert, component, target }) { | ||
component.condition = true; | ||
assert.htmlEqual(target.innerHTML, ` | ||
<div slot="a">hello a</div> | ||
<hr> | ||
<div slot="b">hello b</div> | ||
`); | ||
} | ||
}; |
11 changes: 11 additions & 0 deletions
11
test/runtime/samples/component-conditional-slot-11-slot-attribute/main.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<script> | ||
import Foo from "./Foo.svelte"; | ||
export let condition = false; | ||
</script> | ||
|
||
<Foo> | ||
{#if condition} | ||
<div slot="a">hello a</div> | ||
{/if} | ||
<div slot="b">hello b</div> | ||
</Foo> |
3 changes: 3 additions & 0 deletions
3
test/runtime/samples/component-conditional-slot-12-slot-fowarding/Bar.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
x: <slot name="x">fallback x</slot> | ||
y: <slot name="y">fallback y</slot> | ||
z: <slot name="z">fallback z</slot> |
15 changes: 15 additions & 0 deletions
15
test/runtime/samples/component-conditional-slot-12-slot-fowarding/Foo.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<script> | ||
import Bar from './Bar.svelte'; | ||
export let condition1 = false; | ||
export let condition2 = true; | ||
</script> | ||
|
||
<Bar> | ||
<slot name="a" slot="x">Fallback a</slot> | ||
{#if condition1} | ||
<slot name="b" slot="y">Fallback b</slot> | ||
{/if} | ||
{#if condition2} | ||
<slot name="c" slot="z">Fallback c</slot> | ||
{/if} | ||
</Bar> |
37 changes: 37 additions & 0 deletions
37
test/runtime/samples/component-conditional-slot-12-slot-fowarding/_config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
export default { | ||
html: ` | ||
x: Fallback a | ||
y: fallback y | ||
z: <div slot="c">hello c</div> | ||
`, | ||
test({ assert, component, target }) { | ||
component.condition1 = true; | ||
assert.htmlEqual(target.innerHTML, ` | ||
x: Fallback a | ||
y: <div slot="b">hello b</div> | ||
z: <div slot="c">hello c</div> | ||
`); | ||
|
||
component.condition3 = true; | ||
assert.htmlEqual(target.innerHTML, ` | ||
x: <div slot="a">hello a</div> | ||
y: <div slot="b">hello b</div> | ||
z: <div slot="c">hello c</div> | ||
`); | ||
|
||
component.condition4 = false; | ||
component.condition1 = false; | ||
assert.htmlEqual(target.innerHTML, ` | ||
x: <div slot="a">hello a</div> | ||
y: fallback y | ||
z: <div slot="c">hello c</div> | ||
`); | ||
|
||
component.condition2 = false; | ||
assert.htmlEqual(target.innerHTML, ` | ||
x: <div slot="a">hello a</div> | ||
y: fallback y | ||
z: fallback z | ||
`); | ||
} | ||
}; |
17 changes: 17 additions & 0 deletions
17
test/runtime/samples/component-conditional-slot-12-slot-fowarding/main.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<script> | ||
import Foo from "./Foo.svelte"; | ||
export let condition1; | ||
export let condition2; | ||
export let condition3 = false; | ||
export let condition4 = true; | ||
</script> | ||
|
||
<Foo {condition1} {condition2}> | ||
{#if condition3} | ||
<div slot="a">hello a</div> | ||
{/if} | ||
{#if condition4} | ||
<div slot="b">hello b</div> | ||
{/if} | ||
<div slot="c">hello c</div> | ||
</Foo> |
3 changes: 3 additions & 0 deletions
3
test/runtime/samples/component-conditional-slot-13-slot-fowarding/Bar.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
x: <slot name="x">fallback x</slot> | ||
y: <slot name="y">fallback y</slot> | ||
z: <slot name="z">fallback z</slot> |
9 changes: 9 additions & 0 deletions
9
test/runtime/samples/component-conditional-slot-13-slot-fowarding/Foo.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<script> | ||
import Bar from './Bar.svelte'; | ||
</script> | ||
|
||
<Bar> | ||
<slot name="a" slot="x" /> | ||
<slot name="b" slot="y" /> | ||
<slot name="c" slot="z" /> | ||
</Bar> |
15 changes: 15 additions & 0 deletions
15
test/runtime/samples/component-conditional-slot-13-slot-fowarding/_config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export default { | ||
html: ` | ||
x: fallback x | ||
y: <div slot="b">hello b</div> | ||
z: fallback z | ||
`, | ||
test({ assert, component, target }) { | ||
component.condition = true; | ||
assert.htmlEqual(target.innerHTML, ` | ||
x: <div slot="a">hello a</div> | ||
y: <div slot="b">hello b</div> | ||
z: fallback z | ||
`); | ||
} | ||
}; |
Oops, something went wrong.