dont actually render <slot> elements

pull/787/head
Rich Harris 7 years ago
parent a469b560d8
commit 143d0ea753

@ -353,9 +353,7 @@ const preprocessors = {
}
const name = block.getUniqueName(
node.name === 'slot' ?
`slot_${getStaticAttributeValue(node, 'name') || 'default'}`:
node.name.replace(/[^a-zA-Z0-9_$]/g, '_')
node.name.replace(/[^a-zA-Z0-9_$]/g, '_')
);
node._state = getChildState(state, {

@ -17,38 +17,14 @@ export default function visitSlot(
const slotName = getStaticAttributeValue(node, 'name') || 'default';
generator.slots.add(slotName);
const name = node._state.name;
const content_name = block.getUniqueName(`slot_content_${slotName}`);
block.addVariable(content_name, `#component._slotted.${slotName}`);
block.addVariable(name);
block.addElement(
name,
`@createElement('slot')`,
`@claimElement(${state.parentNodes}, 'slot', {${slotName !== 'default' ? ` name: '${slotName}' ` : ''}})`,
state.parentNode
);
if (generator.hydratable) {
block.builders.claim.addLine(
`var ${node._state.parentNodes} = @children(${name});`
);
}
if (slotName !== 'default') {
block.builders.hydrate.addBlock(deindent`
@setAttribute(${name}, 'name', '${slotName}');
`);
}
block.builders.mount.addLine(
`#component.slots.${slotName} = ${name};`
);
block.builders.unmount.addLine(
`#component.slots.${slotName} = null;`
);
// TODO use surrounds as anchors where possible, a la if/each blocks
const before = block.getUniqueName(`${content_name}_before`);
const after = block.getUniqueName(`${content_name}_after`);
block.addVariable(before);
block.addVariable(after);
block.builders.create.pushCondition(`!${content_name}`);
block.builders.hydrate.pushCondition(`!${content_name}`);
@ -57,7 +33,7 @@ export default function visitSlot(
block.builders.destroy.pushCondition(`!${content_name}`);
node.children.forEach((child: Node) => {
visit(generator, block, node._state, child, elementStack.concat(node), componentStack);
visit(generator, block, state, child, elementStack, componentStack);
});
block.builders.create.popCondition();
@ -67,19 +43,34 @@ export default function visitSlot(
block.builders.destroy.popCondition();
// TODO can we use an else here?
block.builders.mount.addBlock(deindent`
if (${content_name}) {
@appendNode(${content_name}, ${name});
}
`);
if (state.parentNode) {
block.builders.mount.addBlock(deindent`
if (${content_name}) {
@appendNode(${before} || (${before} = @createComment()), ${state.parentNode});
@appendNode(${content_name}, ${state.parentNode});
@appendNode(${after} || (${after} = @createComment()), ${state.parentNode});
}
`);
} else {
block.builders.mount.addBlock(deindent`
if (${content_name}) {
@insertNode(${before} || (${before} = @createComment()), #target, anchor);
@insertNode(${content_name}, #target, anchor);
@insertNode(${after} || (${after} = @createComment()), #target, anchor);
}
`);
}
// if the slot is unmounted, move nodes back into the document fragment,
// so that it can be reinserted later
// TODO so that this can work with public API, component._slotted should
// be all fragments, derived from options.slots. Not === options.slots
// TODO can we use an else here?
block.builders.unmount.addBlock(deindent`
if (${content_name}) {
while (${name}.firstChild) @appendNode(${name}.firstChild, ${content_name});
@reinsertBetween(${before}, ${after}, ${content_name});
@detachNode(${before});
@detachNode(${after});
}
`);
}

@ -12,7 +12,6 @@ export default function visitSlot(
const name = node.attributes.find((attribute: Node) => attribute.name);
const slotName = name && name.value[0].data || 'default';
generator.append(`<slot${slotName !== 'default' ? ` name='${slotName}'` : ''}>`);
generator.append(`\${options && options.slotted && options.slotted.${slotName} ? options.slotted.${slotName}() : '`);
generator.elementDepth += 1;
@ -23,5 +22,5 @@ export default function visitSlot(
generator.elementDepth -= 1;
generator.append(`'}</slot>`);
generator.append(`'}`);
}

@ -16,6 +16,12 @@ export function detachBetween(before, after) {
}
}
export function reinsertBetween(before, after, target) {
while (before.nextSibling && before.nextSibling !== after) {
target.appendChild(before.parentNode.removeChild(before.nextSibling));
}
}
// TODO this is out of date
export function destroyEach(iterations, detach, start) {
for (var i = start; i < iterations.length; i += 1) {

@ -9,15 +9,13 @@ export default {
component.refs.modal.toggle();
assert.htmlEqual(target.innerHTML, `
<slot>
<span>b</span>
<span>b</span>
<select>
<option value='a'>a</option>
<option value='b'>b</option>
<option value='c'>c</option>
</select>
</slot>
<select>
<option value='a'>a</option>
<option value='b'>b</option>
<option value='c'>c</option>
</select>
`);
const select = target.querySelector('select');
@ -34,15 +32,13 @@ export default {
]);
assert.htmlEqual(target.innerHTML, `
<slot>
<span>c</span>
<span>c</span>
<select>
<option value='a'>a</option>
<option value='b'>b</option>
<option value='c'>c</option>
</select>
</slot>
<select>
<option value='a'>a</option>
<option value='b'>b</option>
<option value='c'>c</option>
</select>
`);
component.refs.modal.toggle();
@ -55,15 +51,13 @@ export default {
]);
assert.htmlEqual(target.innerHTML, `
<slot>
<span>c</span>
<span>c</span>
<select>
<option value='a'>a</option>
<option value='b'>b</option>
<option value='c'>c</option>
</select>
</slot>
<select>
<option value='a'>a</option>
<option value='b'>b</option>
<option value='c'>c</option>
</select>
`);
}
};

@ -8,9 +8,9 @@ export default {
html: `
<input type='number'>
<ol>
<li><slot>id-0: value is zero</slot></li>
<li><slot>id-1: value is one</slot></li>
<li><slot>id-2: value is two</slot></li>
<li>id-0: value is zero</li>
<li>id-1: value is one</li>
<li>id-2: value is two</li>
</ol>
`,
@ -23,10 +23,10 @@ export default {
assert.htmlEqual(target.innerHTML, `
<input type='number'>
<ol>
<li><slot>id-0: value is zero</slot></li>
<li><slot>id-1: value is one</slot></li>
<li><slot>id-2: value is two</slot></li>
<li><slot>id-3: value is three</slot></li>
<li>id-0: value is zero</li>
<li>id-1: value is one</li>
<li>id-2: value is two</li>
<li>id-3: value is three</li>
</ol>
`);
}

@ -8,9 +8,9 @@ export default {
html: `
<input type='number'>
<ol>
<li><slot>id-2: value is two</slot></li>
<li><slot>id-1: value is one</slot></li>
<li><slot>id-0: value is zero</slot></li>
<li>id-2: value is two</li>
<li>id-1: value is one</li>
<li>id-0: value is zero</li>
</ol>
`,
@ -23,10 +23,10 @@ export default {
assert.htmlEqual(target.innerHTML, `
<input type='number'>
<ol>
<li><slot>id-3: value is three</slot></li>
<li><slot>id-2: value is two</slot></li>
<li><slot>id-1: value is one</slot></li>
<li><slot>id-0: value is zero</slot></li>
<li>id-3: value is three</li>
<li>id-2: value is two</li>
<li>id-1: value is one</li>
<li>id-0: value is zero</li>
</ol>
`);
}

@ -1,28 +1,28 @@
export default {
html: `
<p><span class=''><slot>1</slot></span></p>
<p><span class='selected'><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class='selected'><slot>2</slot></span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class=''>1</span></p>
<p><span class='selected'>2</span></p>
<p><span class=''>3</span></p>
<p><span class='selected'>2</span></p>
<p><span class=''>1</span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class='selected'><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class='selected'><slot>2</slot></span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class=''>1</span></p>
<p><span class='selected'>2</span></p>
<p><span class=''>3</span></p>
<p><span class='selected'>2</span></p>
<p><span class=''>1</span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class='selected'><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class='selected'><slot>2</slot></span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class=''>1</span></p>
<p><span class='selected'>2</span></p>
<p><span class=''>3</span></p>
<p><span class='selected'>2</span></p>
<p><span class=''>1</span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class='selected'><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class='selected'><slot>2</slot></span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class=''>1</span></p>
<p><span class='selected'>2</span></p>
<p><span class=''>3</span></p>
<p><span class='selected'>2</span></p>
<p><span class=''>1</span></p>
`,
test ( assert, component, target, window ) {
@ -33,58 +33,58 @@ export default {
assert.equal( component.get( 'currentIdentifier' ), 1 );
assert.htmlEqual( target.innerHTML, `
<p><span class='selected'><slot>1</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class='selected'><slot>1</slot></span></p>
<p><span class='selected'>1</span></p>
<p><span class=''>2</span></p>
<p><span class=''>3</span></p>
<p><span class=''>2</span></p>
<p><span class='selected'>1</span></p>
<p><span class='selected'><slot>1</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class='selected'><slot>1</slot></span></p>
<p><span class='selected'>1</span></p>
<p><span class=''>2</span></p>
<p><span class=''>3</span></p>
<p><span class=''>2</span></p>
<p><span class='selected'>1</span></p>
<p><span class='selected'><slot>1</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class='selected'><slot>1</slot></span></p>
<p><span class='selected'>1</span></p>
<p><span class=''>2</span></p>
<p><span class=''>3</span></p>
<p><span class=''>2</span></p>
<p><span class='selected'>1</span></p>
<p><span class='selected'><slot>1</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class='selected'><slot>1</slot></span></p>
<p><span class='selected'>1</span></p>
<p><span class=''>2</span></p>
<p><span class=''>3</span></p>
<p><span class=''>2</span></p>
<p><span class='selected'>1</span></p>
` );
spans[0].dispatchEvent( click );
assert.equal( component.get( 'currentIdentifier' ), null );
assert.htmlEqual( target.innerHTML, `
<p><span class=''><slot>1</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class=''>1</span></p>
<p><span class=''>2</span></p>
<p><span class=''>3</span></p>
<p><span class=''>2</span></p>
<p><span class=''>1</span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class=''>1</span></p>
<p><span class=''>2</span></p>
<p><span class=''>3</span></p>
<p><span class=''>2</span></p>
<p><span class=''>1</span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class=''>1</span></p>
<p><span class=''>2</span></p>
<p><span class=''>3</span></p>
<p><span class=''>2</span></p>
<p><span class=''>1</span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>3</slot></span></p>
<p><span class=''><slot>2</slot></span></p>
<p><span class=''><slot>1</slot></span></p>
<p><span class=''>1</span></p>
<p><span class=''>2</span></p>
<p><span class=''>3</span></p>
<p><span class=''>2</span></p>
<p><span class=''>1</span></p>
` );
}
};

@ -1,3 +1,3 @@
export default {
html: '<p><slot>Hello</slot></p>'
html: '<p>Hello</p>'
};

@ -1,7 +1,3 @@
export default {
html: '<p><slot>Hello</slot></p>',
test(assert, component) {
assert.htmlEqual(component.refs.nested.slots.default.innerHTML, 'Hello');
}
html: '<p>Hello</p>'
};

@ -1,9 +1,9 @@
export default {
html: `
<div>
<slot><p>not fallback</p></slot>
<slot name='bar'><p class='default'>bar fallback content</p></slot>
<slot name='foo'><p class='default'>foo fallback content</p></slot>
<p>not fallback</p>
<p class='default'>bar fallback content</p>
<p class='default'>foo fallback content</p>
</div>
`
};

@ -1,15 +1,9 @@
export default {
html: `
<div>
<slot>Hello</slot>
<slot name='bar'><p slot='bar'>bar</p></slot>
<slot name='foo'><p slot='foo'>foo</p></slot>
Hello
<p slot='bar'>bar</p>
<p slot='foo'>foo</p>
</div>
`,
test(assert, component) {
assert.htmlEqual(component.refs.nested.slots.default.innerHTML, 'Hello');
assert.htmlEqual(component.refs.nested.slots.foo.innerHTML, `<p slot='foo'>foo</p>`);
assert.htmlEqual(component.refs.nested.slots.bar.innerHTML, `<p slot='bar'>bar</p>`);
}
`
};

@ -1,6 +1,6 @@
export default {
html: `
<div>before</div>
<slot>test</slot>
test
`
};

@ -7,10 +7,10 @@ export default {
assert.equal( widget.get( 'show' ), false );
widget.set({show: true});
assert.htmlEqual( target.innerHTML, '<div><p><slot>Hello</slot></p></div>' );
assert.htmlEqual( target.innerHTML, '<div><p>Hello</p></div>' );
component.set({data: 'World'});
assert.htmlEqual( target.innerHTML, '<div><p><slot>World</slot></p></div>' );
assert.htmlEqual( target.innerHTML, '<div><p>World</p></div>' );
widget.set({show: false});
assert.htmlEqual( target.innerHTML, '<div><p></p></div>' );
@ -19,6 +19,6 @@ export default {
assert.htmlEqual( target.innerHTML, '<div><p></p></div>' );
widget.set({show: true});
assert.htmlEqual( target.innerHTML, '<div><p><slot>Goodbye</slot></p></div>' );
assert.htmlEqual( target.innerHTML, '<div><p>Goodbye</p></div>' );
}
};

@ -1,8 +1,8 @@
export default {
html: `
<p><slot>Hello Alice</slot></p>
<p><slot>Hello Bob</slot></p>
<p><slot>Hello Charles</slot></p>
<p>Hello Alice</p>
<p>Hello Bob</p>
<p>Hello Charles</p>
`,
test ( assert, component, target ) {
@ -11,9 +11,9 @@ export default {
});
assert.htmlEqual( target.innerHTML, `
<p><slot>Hello Alice</slot></p>
<p><slot>Hello Charles</slot></p>
<p><slot>Hello Bob</slot></p>
<p>Hello Alice</p>
<p>Hello Charles</p>
<p>Hello Bob</p>
`);
}
};

@ -1,11 +1,11 @@
export default {
html: `
<div><p class='widget'><slot>Hello</slot></p></div>
<div><p class='widget'>Hello</p></div>
`,
test ( assert, component, target ) {
component.set({ arriving: false });
assert.htmlEqual( target.innerHTML, `<div><p class='widget'><slot>Goodbye</slot></p></div>` );
assert.htmlEqual( target.innerHTML, `<div><p class='widget'>Goodbye</p></div>` );
component.destroy();
}

@ -1,7 +1,7 @@
export default {
html: `
<slot>One
Inner</slot>
One
Inner
`,
test ( assert, component, target ) {
@ -9,6 +9,6 @@ export default {
assert.htmlEqual( target.innerHTML, `` );
component.set({ foo: true });
assert.htmlEqual( target.innerHTML, `<slot>One\nInner</slot>` );
assert.htmlEqual( target.innerHTML, `One\nInner` );
}
};

@ -1,6 +1,6 @@
export default {
html: `
<div><p><slot>Hello</slot></p></div>
<div><p>Hello</p></div>
`,
test ( assert, component, target ) {
@ -9,7 +9,7 @@ export default {
component.set({ data: 'World' });
assert.equal( component.get( 'data' ), 'World' );
assert.htmlEqual( target.innerHTML, `
<div><p><slot>World</slot></p></div>
<div><p>World</p></div>
` );
}
};

@ -7,7 +7,7 @@ export default {
<div class='modal-background'></div>
<div class='modal'>
<slot><h2>Hello!</h2></slot>
<h2>Hello!</h2>
<button>close modal</button>
</div>
`,

@ -1,12 +1,12 @@
export default {
html: `
<b><slot>Hello</slot></b>
<b>Hello</b>
`,
test ( assert, component, target ) {
component.set( { name: 'World' } );
assert.htmlEqual( target.innerHTML, `
<b><slot>Hello</slot></b> World
<b>Hello</b> World
` );
}
};

@ -1,6 +1,6 @@
export default {
html: `
<p>Hello
<slot></slot>
</p>`
};

@ -4,8 +4,8 @@ export default {
'skip-ssr': true,
html: `
<div><slot><p>first thing (true)</p></slot></div>
<div><slot><p>second thing (true)</p></slot></div>
<div><p>first thing (true)</p></div>
<div><p>second thing (true)</p></div>
`,
test(assert, component) {

@ -1,3 +1,3 @@
<div>
<p><slot>Hello</slot></p>
<p>Hello</p>
</div>

@ -1,3 +1,3 @@
<div>
<p><slot>Hello</slot></p>
<p>Hello</p>
</div>
Loading…
Cancel
Save