diff --git a/mocha.opts b/mocha.opts index af6b17a845..427b029758 100644 --- a/mocha.opts +++ b/mocha.opts @@ -1,2 +1 @@ ---bail test/test.js \ No newline at end of file diff --git a/src/compile/nodes/Element.ts b/src/compile/nodes/Element.ts index 9fa630124e..33955919ee 100644 --- a/src/compile/nodes/Element.ts +++ b/src/compile/nodes/Element.ts @@ -658,10 +658,10 @@ export default class Element extends Node { const slot = this.attributes.find(attribute => attribute.name === 'slot'); if (slot) { const prop = quotePropIfNecessary(slot.chunks[0].data); - return `@append(${name}._slotted${prop}, ${this.var});`; + return `@append(${name}.$$slotted${prop}, ${this.var});`; } - return `@append(${name}._slotted.default, ${this.var});`; + return `@append(${name}.$$slotted.default, ${this.var});`; } addCssClass(className = this.component.stylesheet.id) { diff --git a/src/compile/nodes/Transition.ts b/src/compile/nodes/Transition.ts index 6e16c57f97..5e6aa922d2 100644 --- a/src/compile/nodes/Transition.ts +++ b/src/compile/nodes/Transition.ts @@ -10,13 +10,6 @@ export default class Transition extends Node { constructor(component, parent, scope, info) { super(component, parent, scope, info); - if (!component.transitions.has(info.name)) { - component.error(info, { - code: `missing-transition`, - message: `Missing transition '${info.name}'` - }); - } - this.name = info.name; this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out'; diff --git a/src/compile/nodes/shared/Node.ts b/src/compile/nodes/shared/Node.ts index ca56375962..4ce51b46c9 100644 --- a/src/compile/nodes/shared/Node.ts +++ b/src/compile/nodes/shared/Node.ts @@ -51,7 +51,7 @@ export default class Node { } remount(name: string) { - return `${this.var}.m(${name}._slotted.default, null);`; + return `${this.var}.m(${name}.$$slotted.default, null);`; } warnIfEmptyBlock() { diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts index 95c109e0a3..fe584a7d45 100644 --- a/src/compile/render-dom/index.ts +++ b/src/compile/render-dom/index.ts @@ -88,8 +88,8 @@ export default function dom( ${renderer.slots.size && deindent` connectedCallback() { - Object.keys(this._slotted).forEach(key => { - this.appendChild(this._slotted[key]); + Object.keys(this.$$slotted).forEach(key => { + this.appendChild(this.$$slotted[key]); }); }`} diff --git a/src/compile/render-dom/wrappers/EachBlock.ts b/src/compile/render-dom/wrappers/EachBlock.ts index 94e20f5d53..bc274e7032 100644 --- a/src/compile/render-dom/wrappers/EachBlock.ts +++ b/src/compile/render-dom/wrappers/EachBlock.ts @@ -501,6 +501,6 @@ export default class EachBlockWrapper extends Wrapper { remount(name: string) { // TODO consider keyed blocks - return `for (var #i = 0; #i < ${this.vars.iterations}.length; #i += 1) ${this.vars.iterations}[#i].m(${name}._slotted.default, null);`; + return `for (var #i = 0; #i < ${this.vars.iterations}.length; #i += 1) ${this.vars.iterations}[#i].m(${name}.$$slotted.default, null);`; } } \ No newline at end of file diff --git a/src/compile/render-dom/wrappers/Element/index.ts b/src/compile/render-dom/wrappers/Element/index.ts index e530d4f1aa..8cfb224416 100644 --- a/src/compile/render-dom/wrappers/Element/index.ts +++ b/src/compile/render-dom/wrappers/Element/index.ts @@ -174,6 +174,9 @@ export default class ElementWrapper extends Wrapper { }); if (this.parent) { + // console.log(`has intro ${!!node.intro}`); + // console.log(`has outro ${!!node.outro}`); + if (node.actions.length > 0) this.parent.cannotUseInnerHTML(); if (node.animation) this.parent.cannotUseInnerHTML(); if (node.bindings.length > 0) this.parent.cannotUseInnerHTML(); @@ -211,7 +214,7 @@ export default class ElementWrapper extends Wrapper { let initialMountNode; if (this.slotOwner) { - initialMountNode = `${this.slotOwner.var}._slotted${prop}`; + initialMountNode = `${this.slotOwner.var}.$$slotted${prop}`; } else { initialMountNode = parentNode; } @@ -714,7 +717,7 @@ export default class ElementWrapper extends Wrapper { block.addVariable(name); - const fn = `%transitions-${intro.name}`; + const fn = `ctx.${intro.name}`; block.builders.intro.addConditional(`#component.root._intro`, deindent` if (${name}) ${name}.invalidate(); @@ -744,7 +747,7 @@ export default class ElementWrapper extends Wrapper { ? intro.expression.snippet : '{}'; - const fn = `%transitions-${intro.name}`; // TODO add built-in transitions? + const fn = `ctx.${intro.name}`; // TODO add built-in transitions? if (outro) { block.builders.intro.addBlock(deindent` @@ -767,7 +770,7 @@ export default class ElementWrapper extends Wrapper { ? outro.expression.snippet : '{}'; - const fn = `%transitions-${outro.name}`; + const fn = `ctx.${outro.name}`; block.builders.intro.addBlock(deindent` if (${outroName}) ${outroName}.abort(1); @@ -900,10 +903,10 @@ export default class ElementWrapper extends Wrapper { const slot = this.attributes.find(attribute => attribute.name === 'slot'); if (slot) { const prop = quotePropIfNecessary(slot.chunks[0].data); - return `@append(${name}._slotted${prop}, ${this.var});`; + return `@append(${name}.$$slotted${prop}, ${this.var});`; } - return `@append(${name}._slotted.default, ${this.var});`; + return `@append(${name}.$$slotted.default, ${this.var});`; } addCssClass(className = this.component.stylesheet.id) { diff --git a/src/compile/render-dom/wrappers/InlineComponent/index.ts b/src/compile/render-dom/wrappers/InlineComponent/index.ts index 07c2d99d68..fb789c5710 100644 --- a/src/compile/render-dom/wrappers/InlineComponent/index.ts +++ b/src/compile/render-dom/wrappers/InlineComponent/index.ts @@ -92,7 +92,7 @@ export default class InlineComponentWrapper extends Wrapper { componentInitProperties.push(`slots: { ${slots.join(', ')} }`); this.fragment.nodes.forEach((child: Wrapper) => { - child.render(block, `${this.var}._slotted.default`, 'nodes'); + child.render(block, `${this.var}.$$slotted.default`, 'nodes'); }); } @@ -471,7 +471,7 @@ export default class InlineComponentWrapper extends Wrapper { } remount(name: string) { - return `${this.var}.$$mount(${name}._slotted.default, null);`; + return `${this.var}.$$mount(${name}.$$slotted.default, null);`; } } diff --git a/src/compile/render-dom/wrappers/Slot.ts b/src/compile/render-dom/wrappers/Slot.ts index 723eb9d2a4..d12464cc61 100644 --- a/src/compile/render-dom/wrappers/Slot.ts +++ b/src/compile/render-dom/wrappers/Slot.ts @@ -49,7 +49,7 @@ export default class SlotWrapper extends Wrapper { const content_name = block.getUniqueName(`slot_content_${sanitize(slotName)}`); const prop = quotePropIfNecessary(slotName); - block.addVariable(content_name, `#component._slotted${prop}`); + block.addVariable(content_name, `#component.$$slotted${prop}`); // TODO can we use isDomNode instead of type === 'Element'? const needsAnchorBefore = this.prev ? this.prev.node.type !== 'Element' : !parentNode; @@ -107,7 +107,7 @@ export default class SlotWrapper extends Wrapper { // 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 + // TODO so that this can work with public API, component.$$slotted should // be all fragments, derived from options.slots. Not === options.slots const unmountLeadin = block.builders.destroy.toString() !== destroyBefore ? `else` diff --git a/src/compile/render-dom/wrappers/Text.ts b/src/compile/render-dom/wrappers/Text.ts index 3d4e99197b..a32e908f63 100644 --- a/src/compile/render-dom/wrappers/Text.ts +++ b/src/compile/render-dom/wrappers/Text.ts @@ -62,6 +62,6 @@ export default class TextWrapper extends Wrapper { } remount(name: string) { - return `@append(${name}._slotted.default, ${this.var});`; + return `@append(${name}.$$slotted.default, ${this.var});`; } } \ No newline at end of file diff --git a/src/compile/render-dom/wrappers/shared/Tag.ts b/src/compile/render-dom/wrappers/shared/Tag.ts index b0b5ec01c3..4829867849 100644 --- a/src/compile/render-dom/wrappers/shared/Tag.ts +++ b/src/compile/render-dom/wrappers/shared/Tag.ts @@ -62,6 +62,6 @@ export default class Tag extends Wrapper { } remount(name: string) { - return `@append(${name}._slotted.default, ${this.var});`; + return `@append(${name}.$$slotted.default, ${this.var});`; } } \ No newline at end of file diff --git a/src/compile/render-dom/wrappers/shared/Wrapper.ts b/src/compile/render-dom/wrappers/shared/Wrapper.ts index cc59e2b6fd..21112f3f55 100644 --- a/src/compile/render-dom/wrappers/shared/Wrapper.ts +++ b/src/compile/render-dom/wrappers/shared/Wrapper.ts @@ -87,6 +87,6 @@ export default class Wrapper { } remount(name: string) { - return `${this.var}.m(${name}._slotted.default, null);`; + return `${this.var}.m(${name}.$$slotted.default, null);`; } } \ No newline at end of file diff --git a/src/internal/SvelteComponent.js b/src/internal/SvelteComponent.js index 36af47e8db..9e6d64db26 100644 --- a/src/internal/SvelteComponent.js +++ b/src/internal/SvelteComponent.js @@ -9,6 +9,8 @@ export class SvelteComponent { this.$$onupdate = []; this.$$ondestroy = []; + this.$$slotted = options.slots; + set_current_component(this); const [get_state, inject_props, inject_refs] = this.$$init( key => this.$$make_dirty(key) diff --git a/src/internal/transitions.js b/src/internal/transitions.js index 8dfa50b8ff..4b039402b2 100644 --- a/src/internal/transitions.js +++ b/src/internal/transitions.js @@ -89,7 +89,8 @@ export function wrapTransition(component, node, fn, params, intro) { }, start(program) { - component.fire(`${program.b ? 'intro' : 'outro'}.start`, { node }); + // TODO find an alternative to this + // component.fire(`${program.b ? 'intro' : 'outro'}.start`, { node }); program.a = this.t; program.delta = program.b - program.a; @@ -128,7 +129,8 @@ export function wrapTransition(component, node, fn, params, intro) { if (obj.tick) obj.tick(this.t, 1 - this.t); - component.fire(`${program.b ? 'intro' : 'outro'}.end`, { node }); + // TODO find an alternative to this + // component.fire(`${program.b ? 'intro' : 'outro'}.end`, { node }); if (!program.b && !program.invalidated) { program.group.callbacks.push(() => { diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts index c9d5aece72..e6c17120a2 100644 --- a/src/parse/state/tag.ts +++ b/src/parse/state/tag.ts @@ -408,15 +408,28 @@ function readAttribute(parser: Parser, uniqueNames: Set) { const end = parser.index; if (type) { - name = name.slice(colon_index + 1); + const directive_name = name.slice(colon_index + 1); - return { + const directive = { start, end, type, - name, - [type === 'Binding' ? 'value' : 'expression']: value[0] && value[0].expression + name: directive_name }; + + if (type === 'Binding') { + directive.value = value[0] && value[0].expression; + } else { + directive.expression = value[0] && value[0].expression; + } + + if (type === 'Transition') { + const direction = name.slice(0, colon_index); + directive.intro = direction === 'in' || direction === 'transition'; + directive.outro = direction === 'out' || direction === 'transition'; + } + + return directive; } return { diff --git a/src/utils/annotateWithScopes.ts b/src/utils/annotateWithScopes.ts index 33f083ac5f..5b0a28efb5 100644 --- a/src/utils/annotateWithScopes.ts +++ b/src/utils/annotateWithScopes.ts @@ -76,6 +76,11 @@ export class Scope { } } + findOwner(name: string): Scope { + if (this.declarations.has(name)) return this; + return this.parent && this.parent.findOwner(name); + } + has(name: string): boolean { return ( this.declarations.has(name) || (this.parent && this.parent.has(name)) diff --git a/test/runtime/samples/autofocus/main.html b/test/runtime/samples/autofocus/main.html index 8bbec2a3c5..0f108d7ba1 100644 --- a/test/runtime/samples/autofocus/main.html +++ b/test/runtime/samples/autofocus/main.html @@ -1,3 +1,7 @@ + + {#if visible} {/if} \ No newline at end of file diff --git a/test/runtime/samples/nested-transition-detach-if-false/Folder.html b/test/runtime/samples/nested-transition-detach-if-false/Folder.html index f0acf1533e..b37ba80b76 100644 --- a/test/runtime/samples/nested-transition-detach-if-false/Folder.html +++ b/test/runtime/samples/nested-transition-detach-if-false/Folder.html @@ -1,9 +1,8 @@