diff --git a/src/generators/dom/preprocess.ts b/src/generators/dom/preprocess.ts index 24663d9796..6beca924ff 100644 --- a/src/generators/dom/preprocess.ts +++ b/src/generators/dom/preprocess.ts @@ -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, { diff --git a/src/generators/dom/visitors/Slot.ts b/src/generators/dom/visitors/Slot.ts index 9a059c138e..85f53f2ca3 100644 --- a/src/generators/dom/visitors/Slot.ts +++ b/src/generators/dom/visitors/Slot.ts @@ -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}); } `); } diff --git a/src/generators/server-side-rendering/visitors/Slot.ts b/src/generators/server-side-rendering/visitors/Slot.ts index 8288b283fe..3886f8a4d9 100644 --- a/src/generators/server-side-rendering/visitors/Slot.ts +++ b/src/generators/server-side-rendering/visitors/Slot.ts @@ -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(``); 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(`'}`); + generator.append(`'}`); } diff --git a/src/shared/dom.js b/src/shared/dom.js index 2ed1173f2d..8408ffd359 100644 --- a/src/shared/dom.js +++ b/src/shared/dom.js @@ -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) { diff --git a/test/runtime/samples/binding-select-in-yield/_config.js b/test/runtime/samples/binding-select-in-yield/_config.js index 927a8a14a1..4ff851d33f 100644 --- a/test/runtime/samples/binding-select-in-yield/_config.js +++ b/test/runtime/samples/binding-select-in-yield/_config.js @@ -9,15 +9,13 @@ export default { component.refs.modal.toggle(); assert.htmlEqual(target.innerHTML, ` - - b + b - - + `); const select = target.querySelector('select'); @@ -34,15 +32,13 @@ export default { ]); assert.htmlEqual(target.innerHTML, ` - - c + c - - + `); component.refs.modal.toggle(); @@ -55,15 +51,13 @@ export default { ]); assert.htmlEqual(target.innerHTML, ` - - c + c - - + `); } }; diff --git a/test/runtime/samples/component-binding-blowback-b/_config.js b/test/runtime/samples/component-binding-blowback-b/_config.js index 9e32ad9a91..7f2bd38d9b 100644 --- a/test/runtime/samples/component-binding-blowback-b/_config.js +++ b/test/runtime/samples/component-binding-blowback-b/_config.js @@ -8,9 +8,9 @@ export default { html: `
    -
  1. id-0: value is zero
  2. -
  3. id-1: value is one
  4. -
  5. id-2: value is two
  6. +
  7. id-0: value is zero
  8. +
  9. id-1: value is one
  10. +
  11. id-2: value is two
`, @@ -23,10 +23,10 @@ export default { assert.htmlEqual(target.innerHTML, `
    -
  1. id-0: value is zero
  2. -
  3. id-1: value is one
  4. -
  5. id-2: value is two
  6. -
  7. id-3: value is three
  8. +
  9. id-0: value is zero
  10. +
  11. id-1: value is one
  12. +
  13. id-2: value is two
  14. +
  15. id-3: value is three
`); } diff --git a/test/runtime/samples/component-binding-blowback-c/_config.js b/test/runtime/samples/component-binding-blowback-c/_config.js index 1d2cdbe2b2..78c3e915fd 100644 --- a/test/runtime/samples/component-binding-blowback-c/_config.js +++ b/test/runtime/samples/component-binding-blowback-c/_config.js @@ -8,9 +8,9 @@ export default { html: `
    -
  1. id-2: value is two
  2. -
  3. id-1: value is one
  4. -
  5. id-0: value is zero
  6. +
  7. id-2: value is two
  8. +
  9. id-1: value is one
  10. +
  11. id-0: value is zero
`, @@ -23,10 +23,10 @@ export default { assert.htmlEqual(target.innerHTML, `
    -
  1. id-3: value is three
  2. -
  3. id-2: value is two
  4. -
  5. id-1: value is one
  6. -
  7. id-0: value is zero
  8. +
  9. id-3: value is three
  10. +
  11. id-2: value is two
  12. +
  13. id-1: value is one
  14. +
  15. id-0: value is zero
`); } diff --git a/test/runtime/samples/component-binding-infinite-loop/_config.js b/test/runtime/samples/component-binding-infinite-loop/_config.js index 3668227e21..6a379af0a4 100644 --- a/test/runtime/samples/component-binding-infinite-loop/_config.js +++ b/test/runtime/samples/component-binding-infinite-loop/_config.js @@ -1,28 +1,28 @@ export default { html: ` -

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

-

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

-

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

-

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

`, test ( assert, component, target, window ) { @@ -33,58 +33,58 @@ export default { assert.equal( component.get( 'currentIdentifier' ), 1 ); assert.htmlEqual( target.innerHTML, ` -

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

-

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

-

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

-

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

` ); spans[0].dispatchEvent( click ); assert.equal( component.get( 'currentIdentifier' ), null ); assert.htmlEqual( target.innerHTML, ` -

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

-

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

-

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

-

1

-

2

-

3

-

2

-

1

+

1

+

2

+

3

+

2

+

1

` ); } }; diff --git a/test/runtime/samples/component-not-void/_config.js b/test/runtime/samples/component-not-void/_config.js index 01d610e458..174d01f1a5 100644 --- a/test/runtime/samples/component-not-void/_config.js +++ b/test/runtime/samples/component-not-void/_config.js @@ -1,3 +1,3 @@ export default { - html: '

Hello

' + html: '

Hello

' }; diff --git a/test/runtime/samples/component-slot-default/_config.js b/test/runtime/samples/component-slot-default/_config.js index 04ea8d044a..174d01f1a5 100644 --- a/test/runtime/samples/component-slot-default/_config.js +++ b/test/runtime/samples/component-slot-default/_config.js @@ -1,7 +1,3 @@ export default { - html: '

Hello

', - - test(assert, component) { - assert.htmlEqual(component.refs.nested.slots.default.innerHTML, 'Hello'); - } + html: '

Hello

' }; diff --git a/test/runtime/samples/component-slot-fallback/_config.js b/test/runtime/samples/component-slot-fallback/_config.js index 14e7ad403b..64f770b5a4 100644 --- a/test/runtime/samples/component-slot-fallback/_config.js +++ b/test/runtime/samples/component-slot-fallback/_config.js @@ -1,9 +1,9 @@ export default { html: `
-

not fallback

-

bar fallback content

-

foo fallback content

+

not fallback

+

bar fallback content

+

foo fallback content

` }; diff --git a/test/runtime/samples/component-slot-named/_config.js b/test/runtime/samples/component-slot-named/_config.js index 251ded4a65..330e219242 100644 --- a/test/runtime/samples/component-slot-named/_config.js +++ b/test/runtime/samples/component-slot-named/_config.js @@ -1,15 +1,9 @@ export default { html: `
- Hello -

bar

-

foo

+ Hello +

bar

+

foo

- `, - - test(assert, component) { - assert.htmlEqual(component.refs.nested.slots.default.innerHTML, 'Hello'); - assert.htmlEqual(component.refs.nested.slots.foo.innerHTML, `

foo

`); - assert.htmlEqual(component.refs.nested.slots.bar.innerHTML, `

bar

`); - } + ` }; diff --git a/test/runtime/samples/component-yield-follows-element/_config.js b/test/runtime/samples/component-yield-follows-element/_config.js index 390a349ccd..93703c7dab 100644 --- a/test/runtime/samples/component-yield-follows-element/_config.js +++ b/test/runtime/samples/component-yield-follows-element/_config.js @@ -1,6 +1,6 @@ export default { html: `
before
- test + test ` }; diff --git a/test/runtime/samples/component-yield-if/_config.js b/test/runtime/samples/component-yield-if/_config.js index 8bc6fec66a..a428e4522d 100644 --- a/test/runtime/samples/component-yield-if/_config.js +++ b/test/runtime/samples/component-yield-if/_config.js @@ -7,10 +7,10 @@ export default { assert.equal( widget.get( 'show' ), false ); widget.set({show: true}); - assert.htmlEqual( target.innerHTML, '

Hello

' ); + assert.htmlEqual( target.innerHTML, '

Hello

' ); component.set({data: 'World'}); - assert.htmlEqual( target.innerHTML, '

World

' ); + assert.htmlEqual( target.innerHTML, '

World

' ); widget.set({show: false}); assert.htmlEqual( target.innerHTML, '

' ); @@ -19,6 +19,6 @@ export default { assert.htmlEqual( target.innerHTML, '

' ); widget.set({show: true}); - assert.htmlEqual( target.innerHTML, '

Goodbye

' ); + assert.htmlEqual( target.innerHTML, '

Goodbye

' ); } }; diff --git a/test/runtime/samples/component-yield-multiple-in-each/_config.js b/test/runtime/samples/component-yield-multiple-in-each/_config.js index dec002f6e9..3669b3f90b 100644 --- a/test/runtime/samples/component-yield-multiple-in-each/_config.js +++ b/test/runtime/samples/component-yield-multiple-in-each/_config.js @@ -1,8 +1,8 @@ export default { html: ` -

Hello Alice

-

Hello Bob

-

Hello Charles

+

Hello Alice

+

Hello Bob

+

Hello Charles

`, test ( assert, component, target ) { @@ -11,9 +11,9 @@ export default { }); assert.htmlEqual( target.innerHTML, ` -

Hello Alice

-

Hello Charles

-

Hello Bob

+

Hello Alice

+

Hello Charles

+

Hello Bob

`); } }; diff --git a/test/runtime/samples/component-yield-multiple-in-if/_config.js b/test/runtime/samples/component-yield-multiple-in-if/_config.js index 15808c86b6..1460962e7a 100644 --- a/test/runtime/samples/component-yield-multiple-in-if/_config.js +++ b/test/runtime/samples/component-yield-multiple-in-if/_config.js @@ -1,11 +1,11 @@ export default { html: ` -

Hello

+

Hello

`, test ( assert, component, target ) { component.set({ arriving: false }); - assert.htmlEqual( target.innerHTML, `

Goodbye

` ); + assert.htmlEqual( target.innerHTML, `

Goodbye

` ); component.destroy(); } diff --git a/test/runtime/samples/component-yield-nested-if/_config.js b/test/runtime/samples/component-yield-nested-if/_config.js index e623b1875f..44548b2f16 100644 --- a/test/runtime/samples/component-yield-nested-if/_config.js +++ b/test/runtime/samples/component-yield-nested-if/_config.js @@ -1,7 +1,7 @@ export default { html: ` - One - Inner + One + Inner `, test ( assert, component, target ) { @@ -9,6 +9,6 @@ export default { assert.htmlEqual( target.innerHTML, `` ); component.set({ foo: true }); - assert.htmlEqual( target.innerHTML, `One\nInner` ); + assert.htmlEqual( target.innerHTML, `One\nInner` ); } }; diff --git a/test/runtime/samples/component-yield-parent/_config.js b/test/runtime/samples/component-yield-parent/_config.js index 2aafa0f982..b80ee68bdb 100644 --- a/test/runtime/samples/component-yield-parent/_config.js +++ b/test/runtime/samples/component-yield-parent/_config.js @@ -1,6 +1,6 @@ export default { html: ` -

Hello

+

Hello

`, test ( assert, component, target ) { @@ -9,7 +9,7 @@ export default { component.set({ data: 'World' }); assert.equal( component.get( 'data' ), 'World' ); assert.htmlEqual( target.innerHTML, ` -

World

+

World

` ); } }; diff --git a/test/runtime/samples/component-yield-placement/_config.js b/test/runtime/samples/component-yield-placement/_config.js index 6c3b08961a..6e5a7d4b73 100644 --- a/test/runtime/samples/component-yield-placement/_config.js +++ b/test/runtime/samples/component-yield-placement/_config.js @@ -7,7 +7,7 @@ export default { `, diff --git a/test/runtime/samples/component-yield-static/_config.js b/test/runtime/samples/component-yield-static/_config.js index 05acc4edf7..06bcd82882 100644 --- a/test/runtime/samples/component-yield-static/_config.js +++ b/test/runtime/samples/component-yield-static/_config.js @@ -1,12 +1,12 @@ export default { html: ` - Hello + Hello `, test ( assert, component, target ) { component.set( { name: 'World' } ); assert.htmlEqual( target.innerHTML, ` - Hello World + Hello World ` ); } }; diff --git a/test/runtime/samples/component-yield/_config.js b/test/runtime/samples/component-yield/_config.js index 07459ac8b3..86cb924c9b 100644 --- a/test/runtime/samples/component-yield/_config.js +++ b/test/runtime/samples/component-yield/_config.js @@ -1,6 +1,6 @@ export default { html: `

Hello - +

` }; diff --git a/test/runtime/samples/flush-before-bindings/_config.js b/test/runtime/samples/flush-before-bindings/_config.js index e28737b19c..1f731d6a34 100644 --- a/test/runtime/samples/flush-before-bindings/_config.js +++ b/test/runtime/samples/flush-before-bindings/_config.js @@ -4,8 +4,8 @@ export default { 'skip-ssr': true, html: ` -

first thing (true)

-

second thing (true)

+

first thing (true)

+

second thing (true)

`, test(assert, component) { diff --git a/test/server-side-rendering/samples/component-yield/_actual.html b/test/server-side-rendering/samples/component-yield/_actual.html index b76eab3af6..49139417a2 100644 --- a/test/server-side-rendering/samples/component-yield/_actual.html +++ b/test/server-side-rendering/samples/component-yield/_actual.html @@ -1,3 +1,3 @@
-

Hello

+

Hello

\ No newline at end of file diff --git a/test/server-side-rendering/samples/component-yield/_expected.html b/test/server-side-rendering/samples/component-yield/_expected.html index b76eab3af6..49139417a2 100644 --- a/test/server-side-rendering/samples/component-yield/_expected.html +++ b/test/server-side-rendering/samples/component-yield/_expected.html @@ -1,3 +1,3 @@
-

Hello

+

Hello

\ No newline at end of file