Skip to content

Commit 3879d52

Browse files
committed
dont slot elements inside custom elements - fixes #827
1 parent 5ed74df commit 3879d52

File tree

5 files changed

+28
-4
lines changed

5 files changed

+28
-4
lines changed

src/generators/dom/preprocess.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Block from './Block';
22
import { trimStart, trimEnd } from '../../utils/trim';
33
import { assign } from '../../shared/index.js';
44
import getStaticAttributeValue from '../../utils/getStaticAttributeValue';
5+
import isChildOfComponent from '../shared/utils/isChildOfComponent';
56
import { DomGenerator } from './index';
67
import { Node } from '../../interfaces';
78
import { State } from './interfaces';
@@ -340,7 +341,8 @@ const preprocessors = {
340341
});
341342
} else {
342343
const slot = getStaticAttributeValue(node, 'slot');
343-
if (slot) {
344+
if (slot && isChildOfComponent(node, generator)) {
345+
node.slotted = true;
344346
// TODO validate slots — no nesting, no dynamic names...
345347
const component = componentStack[componentStack.length - 1];
346348
component._slots.add(slot);

src/generators/dom/visitors/Element/Element.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export default function visitElement(
6363
const name = childState.parentNode;
6464

6565
const slot = node.attributes.find((attribute: Node) => attribute.name === 'slot');
66-
const parentNode = slot ?
66+
const parentNode = node.slotted ?
6767
`${componentStack[componentStack.length - 1].var}._slotted.${slot.value[0].data}` : // TODO this looks bonkers
6868
state.parentNode;
6969

src/generators/server-side-rendering/preprocess.ts

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import getStaticAttributeValue from '../../utils/getStaticAttributeValue';
2+
import isChildOfComponent from '../shared/utils/isChildOfComponent';
13
import { SsrGenerator } from './index';
24
import { Node } from '../../interfaces';
35

@@ -62,6 +64,11 @@ const preprocessors = {
6264

6365
if (!isComponent) {
6466
generator.stylesheet.apply(node, elementStack);
67+
68+
const slot = getStaticAttributeValue(node, 'slot');
69+
if (slot && isChildOfComponent(node, generator)) {
70+
node.slotted = true;
71+
}
6572
}
6673

6774
if (node.children.length) {
@@ -80,6 +87,8 @@ function preprocessChildren(
8087
elementStack: Node[]
8188
) {
8289
node.children.forEach((child: Node, i: number) => {
90+
child.parent = node;
91+
8392
const preprocessor = preprocessors[child.type];
8493
if (preprocessor) preprocessor(generator, child, elementStack);
8594
});

src/generators/server-side-rendering/visitors/Element.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ export default function visitElement(
4747
let openingTag = `<${node.name}`;
4848
let textareaContents; // awkward special case
4949

50-
const slot = node.attributes.find((attribute: Node) => attribute.name === 'slot');
51-
if (slot) {
50+
if (node.slotted) {
51+
const slot = node.attributes.find((attribute: Node) => attribute.name === 'slot');
5252
const slotName = slot.value[0].data;
5353
const appendTarget = generator.appendTargets[generator.appendTargets.length - 1];
5454
appendTarget.slotStack.push(slotName);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Node } from '../../../interfaces';
2+
import Generator from '../../Generator';
3+
4+
export default function isChildOfComponent(node: Node, generator: Generator) {
5+
while (node = node.parent) {
6+
if (node.type !== 'Element') continue;
7+
if (generator.components.has(node.name)) return true;
8+
if (/-/.test(node.name)) return false;
9+
}
10+
11+
// TODO do this in validation
12+
throw new Error(`Element with a slot='...' attribute must be a descendant of a component or custom element`);
13+
}

0 commit comments

Comments
 (0)