only use comments around <slot> as necessary

pull/803/head
Rich Harris 7 years ago
parent 6e9f9633b0
commit d1a6f9c11e

@ -20,11 +20,19 @@ export default function visitSlot(
const content_name = block.getUniqueName(`slot_content_${slotName}`); const content_name = block.getUniqueName(`slot_content_${slotName}`);
block.addVariable(content_name, `#component._slotted.${slotName}`); block.addVariable(content_name, `#component._slotted.${slotName}`);
// TODO use surrounds as anchors where possible, a la if/each blocks const needsAnchorBefore = node.prev ? node.prev.type !== 'Element' : !state.parentNode;
const before = block.getUniqueName(`${content_name}_before`); const needsAnchorAfter = node.next ? node.next.type !== 'Element' : !state.parentNode;
const after = block.getUniqueName(`${content_name}_after`);
block.addVariable(before); const anchorBefore = needsAnchorBefore
block.addVariable(after); ? block.getUniqueName(`${content_name}_before`)
: (node.prev && node.prev.var) || 'null';
const anchorAfter = needsAnchorAfter
? block.getUniqueName(`${content_name}_after`)
: (node.next && node.next.var) || 'null';
if (needsAnchorBefore) block.addVariable(anchorBefore);
if (needsAnchorAfter) block.addVariable(anchorAfter);
block.builders.create.pushCondition(`!${content_name}`); block.builders.create.pushCondition(`!${content_name}`);
block.builders.hydrate.pushCondition(`!${content_name}`); block.builders.hydrate.pushCondition(`!${content_name}`);
@ -46,17 +54,17 @@ export default function visitSlot(
if (state.parentNode) { if (state.parentNode) {
block.builders.mount.addBlock(deindent` block.builders.mount.addBlock(deindent`
if (${content_name}) { if (${content_name}) {
@appendNode(${before} || (${before} = @createComment()), ${state.parentNode}); ${needsAnchorBefore && `@appendNode(${anchorBefore} || (${anchorBefore} = @createComment()), ${state.parentNode});`}
@appendNode(${content_name}, ${state.parentNode}); @appendNode(${content_name}, ${state.parentNode});
@appendNode(${after} || (${after} = @createComment()), ${state.parentNode}); ${needsAnchorAfter && `@appendNode(${anchorAfter} || (${anchorAfter} = @createComment()), ${state.parentNode});`}
} }
`); `);
} else { } else {
block.builders.mount.addBlock(deindent` block.builders.mount.addBlock(deindent`
if (${content_name}) { if (${content_name}) {
@insertNode(${before} || (${before} = @createComment()), #target, anchor); ${needsAnchorBefore && `@insertNode(${anchorBefore} || (${anchorBefore} = @createComment()), #target, anchor);`}
@insertNode(${content_name}, #target, anchor); @insertNode(${content_name}, #target, anchor);
@insertNode(${after} || (${after} = @createComment()), #target, anchor); ${needsAnchorAfter && `@insertNode(${anchorAfter} || (${anchorAfter} = @createComment()), #target, anchor);`}
} }
`); `);
} }
@ -66,11 +74,31 @@ export default function visitSlot(
// TODO so that this can work with public API, component._slotted should // TODO so that this can work with public API, component._slotted should
// be all fragments, derived from options.slots. Not === options.slots // be all fragments, derived from options.slots. Not === options.slots
// TODO can we use an else here? // TODO can we use an else here?
if (anchorBefore === 'null' && anchorAfter === 'null') {
block.builders.unmount.addBlock(deindent` block.builders.unmount.addBlock(deindent`
if (${content_name}) { if (${content_name}) {
@reinsertBetween(${before}, ${after}, ${content_name}); @reinsertChildren(${state.parentNode}, ${content_name});
@detachNode(${before});
@detachNode(${after});
} }
`); `);
} else if (anchorBefore === 'null') {
block.builders.unmount.addBlock(deindent`
if (${content_name}) {
@reinsertBefore(${anchorAfter}, ${content_name});
}
`);
} else if (anchorAfter === 'null') {
block.builders.unmount.addBlock(deindent`
if (${content_name}) {
@reinsertAfter(${anchorBefore}, ${content_name});
}
`);
} else {
block.builders.unmount.addBlock(deindent`
if (${content_name}) {
@reinsertBetween(${anchorBefore}, ${anchorAfter}, ${content_name});
@detachNode(${anchorBefore});
@detachNode(${anchorAfter});
}
`);
}
} }

@ -34,6 +34,19 @@ export function reinsertBetween(before, after, target) {
} }
} }
export function reinsertChildren(parent, target) {
while (parent.firstChild) target.appendChild(parent.firstChild);
}
export function reinsertAfter(before, target) {
while (before.nextSibling) target.appendChild(before.nextSibling);
}
export function reinsertBefore(after, target) {
var parent = after.parentNode;
while (parent.firstChild !== after) target.appendChild(parent.firstChild);
}
// TODO this is out of date // TODO this is out of date
export function destroyEach(iterations, detach, start) { export function destroyEach(iterations, detach, start) {
for (var i = start; i < iterations.length; i += 1) { for (var i = start; i < iterations.length; i += 1) {

Loading…
Cancel
Save