Skip to content

Commit 143d0ea

Browse files
committed
dont actually render <slot> elements
1 parent a469b56 commit 143d0ea

File tree

24 files changed

+161
-183
lines changed

24 files changed

+161
-183
lines changed

src/generators/dom/preprocess.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,7 @@ const preprocessors = {
353353
}
354354

355355
const name = block.getUniqueName(
356-
node.name === 'slot' ?
357-
`slot_${getStaticAttributeValue(node, 'name') || 'default'}`:
358-
node.name.replace(/[^a-zA-Z0-9_$]/g, '_')
356+
node.name.replace(/[^a-zA-Z0-9_$]/g, '_')
359357
);
360358

361359
node._state = getChildState(state, {

src/generators/dom/visitors/Slot.ts

+27-36
Original file line numberDiff line numberDiff line change
@@ -17,38 +17,14 @@ export default function visitSlot(
1717
const slotName = getStaticAttributeValue(node, 'name') || 'default';
1818
generator.slots.add(slotName);
1919

20-
const name = node._state.name;
2120
const content_name = block.getUniqueName(`slot_content_${slotName}`);
22-
2321
block.addVariable(content_name, `#component._slotted.${slotName}`);
2422

25-
block.addVariable(name);
26-
block.addElement(
27-
name,
28-
`@createElement('slot')`,
29-
`@claimElement(${state.parentNodes}, 'slot', {${slotName !== 'default' ? ` name: '${slotName}' ` : ''}})`,
30-
state.parentNode
31-
);
32-
33-
if (generator.hydratable) {
34-
block.builders.claim.addLine(
35-
`var ${node._state.parentNodes} = @children(${name});`
36-
);
37-
}
38-
39-
if (slotName !== 'default') {
40-
block.builders.hydrate.addBlock(deindent`
41-
@setAttribute(${name}, 'name', '${slotName}');
42-
`);
43-
}
44-
45-
block.builders.mount.addLine(
46-
`#component.slots.${slotName} = ${name};`
47-
);
48-
49-
block.builders.unmount.addLine(
50-
`#component.slots.${slotName} = null;`
51-
);
23+
// TODO use surrounds as anchors where possible, a la if/each blocks
24+
const before = block.getUniqueName(`${content_name}_before`);
25+
const after = block.getUniqueName(`${content_name}_after`);
26+
block.addVariable(before);
27+
block.addVariable(after);
5228

5329
block.builders.create.pushCondition(`!${content_name}`);
5430
block.builders.hydrate.pushCondition(`!${content_name}`);
@@ -57,7 +33,7 @@ export default function visitSlot(
5733
block.builders.destroy.pushCondition(`!${content_name}`);
5834

5935
node.children.forEach((child: Node) => {
60-
visit(generator, block, node._state, child, elementStack.concat(node), componentStack);
36+
visit(generator, block, state, child, elementStack, componentStack);
6137
});
6238

6339
block.builders.create.popCondition();
@@ -67,19 +43,34 @@ export default function visitSlot(
6743
block.builders.destroy.popCondition();
6844

6945
// TODO can we use an else here?
70-
block.builders.mount.addBlock(deindent`
71-
if (${content_name}) {
72-
@appendNode(${content_name}, ${name});
73-
}
74-
`);
46+
if (state.parentNode) {
47+
block.builders.mount.addBlock(deindent`
48+
if (${content_name}) {
49+
@appendNode(${before} || (${before} = @createComment()), ${state.parentNode});
50+
@appendNode(${content_name}, ${state.parentNode});
51+
@appendNode(${after} || (${after} = @createComment()), ${state.parentNode});
52+
}
53+
`);
54+
} else {
55+
block.builders.mount.addBlock(deindent`
56+
if (${content_name}) {
57+
@insertNode(${before} || (${before} = @createComment()), #target, anchor);
58+
@insertNode(${content_name}, #target, anchor);
59+
@insertNode(${after} || (${after} = @createComment()), #target, anchor);
60+
}
61+
`);
62+
}
7563

7664
// if the slot is unmounted, move nodes back into the document fragment,
7765
// so that it can be reinserted later
7866
// TODO so that this can work with public API, component._slotted should
7967
// be all fragments, derived from options.slots. Not === options.slots
68+
// TODO can we use an else here?
8069
block.builders.unmount.addBlock(deindent`
8170
if (${content_name}) {
82-
while (${name}.firstChild) @appendNode(${name}.firstChild, ${content_name});
71+
@reinsertBetween(${before}, ${after}, ${content_name});
72+
@detachNode(${before});
73+
@detachNode(${after});
8374
}
8475
`);
8576
}

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ export default function visitSlot(
1212
const name = node.attributes.find((attribute: Node) => attribute.name);
1313
const slotName = name && name.value[0].data || 'default';
1414

15-
generator.append(`<slot${slotName !== 'default' ? ` name='${slotName}'` : ''}>`);
1615
generator.append(`\${options && options.slotted && options.slotted.${slotName} ? options.slotted.${slotName}() : '`);
1716

1817
generator.elementDepth += 1;
@@ -23,5 +22,5 @@ export default function visitSlot(
2322

2423
generator.elementDepth -= 1;
2524

26-
generator.append(`'}</slot>`);
25+
generator.append(`'}`);
2726
}

src/shared/dom.js

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ export function detachBetween(before, after) {
1616
}
1717
}
1818

19+
export function reinsertBetween(before, after, target) {
20+
while (before.nextSibling && before.nextSibling !== after) {
21+
target.appendChild(before.parentNode.removeChild(before.nextSibling));
22+
}
23+
}
24+
1925
// TODO this is out of date
2026
export function destroyEach(iterations, detach, start) {
2127
for (var i = start; i < iterations.length; i += 1) {

test/runtime/samples/binding-select-in-yield/_config.js

+18-24
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@ export default {
99
component.refs.modal.toggle();
1010

1111
assert.htmlEqual(target.innerHTML, `
12-
<slot>
13-
<span>b</span>
12+
<span>b</span>
1413
15-
<select>
16-
<option value='a'>a</option>
17-
<option value='b'>b</option>
18-
<option value='c'>c</option>
19-
</select>
20-
</slot>
14+
<select>
15+
<option value='a'>a</option>
16+
<option value='b'>b</option>
17+
<option value='c'>c</option>
18+
</select>
2119
`);
2220

2321
const select = target.querySelector('select');
@@ -34,15 +32,13 @@ export default {
3432
]);
3533

3634
assert.htmlEqual(target.innerHTML, `
37-
<slot>
38-
<span>c</span>
35+
<span>c</span>
3936
40-
<select>
41-
<option value='a'>a</option>
42-
<option value='b'>b</option>
43-
<option value='c'>c</option>
44-
</select>
45-
</slot>
37+
<select>
38+
<option value='a'>a</option>
39+
<option value='b'>b</option>
40+
<option value='c'>c</option>
41+
</select>
4642
`);
4743

4844
component.refs.modal.toggle();
@@ -55,15 +51,13 @@ export default {
5551
]);
5652

5753
assert.htmlEqual(target.innerHTML, `
58-
<slot>
59-
<span>c</span>
54+
<span>c</span>
6055
61-
<select>
62-
<option value='a'>a</option>
63-
<option value='b'>b</option>
64-
<option value='c'>c</option>
65-
</select>
66-
</slot>
56+
<select>
57+
<option value='a'>a</option>
58+
<option value='b'>b</option>
59+
<option value='c'>c</option>
60+
</select>
6761
`);
6862
}
6963
};

test/runtime/samples/component-binding-blowback-b/_config.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ export default {
88
html: `
99
<input type='number'>
1010
<ol>
11-
<li><slot>id-0: value is zero</slot></li>
12-
<li><slot>id-1: value is one</slot></li>
13-
<li><slot>id-2: value is two</slot></li>
11+
<li>id-0: value is zero</li>
12+
<li>id-1: value is one</li>
13+
<li>id-2: value is two</li>
1414
</ol>
1515
`,
1616

@@ -23,10 +23,10 @@ export default {
2323
assert.htmlEqual(target.innerHTML, `
2424
<input type='number'>
2525
<ol>
26-
<li><slot>id-0: value is zero</slot></li>
27-
<li><slot>id-1: value is one</slot></li>
28-
<li><slot>id-2: value is two</slot></li>
29-
<li><slot>id-3: value is three</slot></li>
26+
<li>id-0: value is zero</li>
27+
<li>id-1: value is one</li>
28+
<li>id-2: value is two</li>
29+
<li>id-3: value is three</li>
3030
</ol>
3131
`);
3232
}

test/runtime/samples/component-binding-blowback-c/_config.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ export default {
88
html: `
99
<input type='number'>
1010
<ol>
11-
<li><slot>id-2: value is two</slot></li>
12-
<li><slot>id-1: value is one</slot></li>
13-
<li><slot>id-0: value is zero</slot></li>
11+
<li>id-2: value is two</li>
12+
<li>id-1: value is one</li>
13+
<li>id-0: value is zero</li>
1414
</ol>
1515
`,
1616

@@ -23,10 +23,10 @@ export default {
2323
assert.htmlEqual(target.innerHTML, `
2424
<input type='number'>
2525
<ol>
26-
<li><slot>id-3: value is three</slot></li>
27-
<li><slot>id-2: value is two</slot></li>
28-
<li><slot>id-1: value is one</slot></li>
29-
<li><slot>id-0: value is zero</slot></li>
26+
<li>id-3: value is three</li>
27+
<li>id-2: value is two</li>
28+
<li>id-1: value is one</li>
29+
<li>id-0: value is zero</li>
3030
</ol>
3131
`);
3232
}

0 commit comments

Comments
 (0)