some slots and transitions stuff

pull/1864/head
Rich Harris 7 years ago
parent 5d34f752b8
commit e30f96a535

@ -1,2 +1 @@
--bail
test/test.js test/test.js

@ -658,10 +658,10 @@ export default class Element extends Node {
const slot = this.attributes.find(attribute => attribute.name === 'slot'); const slot = this.attributes.find(attribute => attribute.name === 'slot');
if (slot) { if (slot) {
const prop = quotePropIfNecessary(slot.chunks[0].data); 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) { addCssClass(className = this.component.stylesheet.id) {

@ -10,13 +10,6 @@ export default class Transition extends Node {
constructor(component, parent, scope, info) { constructor(component, parent, scope, info) {
super(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.name = info.name;
this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out'; this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out';

@ -51,7 +51,7 @@ export default class Node {
} }
remount(name: string) { remount(name: string) {
return `${this.var}.m(${name}._slotted.default, null);`; return `${this.var}.m(${name}.$$slotted.default, null);`;
} }
warnIfEmptyBlock() { warnIfEmptyBlock() {

@ -88,8 +88,8 @@ export default function dom(
${renderer.slots.size && deindent` ${renderer.slots.size && deindent`
connectedCallback() { connectedCallback() {
Object.keys(this._slotted).forEach(key => { Object.keys(this.$$slotted).forEach(key => {
this.appendChild(this._slotted[key]); this.appendChild(this.$$slotted[key]);
}); });
}`} }`}

@ -501,6 +501,6 @@ export default class EachBlockWrapper extends Wrapper {
remount(name: string) { remount(name: string) {
// TODO consider keyed blocks // 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);`;
} }
} }

@ -174,6 +174,9 @@ export default class ElementWrapper extends Wrapper {
}); });
if (this.parent) { 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.actions.length > 0) this.parent.cannotUseInnerHTML();
if (node.animation) this.parent.cannotUseInnerHTML(); if (node.animation) this.parent.cannotUseInnerHTML();
if (node.bindings.length > 0) this.parent.cannotUseInnerHTML(); if (node.bindings.length > 0) this.parent.cannotUseInnerHTML();
@ -211,7 +214,7 @@ export default class ElementWrapper extends Wrapper {
let initialMountNode; let initialMountNode;
if (this.slotOwner) { if (this.slotOwner) {
initialMountNode = `${this.slotOwner.var}._slotted${prop}`; initialMountNode = `${this.slotOwner.var}.$$slotted${prop}`;
} else { } else {
initialMountNode = parentNode; initialMountNode = parentNode;
} }
@ -714,7 +717,7 @@ export default class ElementWrapper extends Wrapper {
block.addVariable(name); block.addVariable(name);
const fn = `%transitions-${intro.name}`; const fn = `ctx.${intro.name}`;
block.builders.intro.addConditional(`#component.root._intro`, deindent` block.builders.intro.addConditional(`#component.root._intro`, deindent`
if (${name}) ${name}.invalidate(); if (${name}) ${name}.invalidate();
@ -744,7 +747,7 @@ export default class ElementWrapper extends Wrapper {
? intro.expression.snippet ? 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) { if (outro) {
block.builders.intro.addBlock(deindent` block.builders.intro.addBlock(deindent`
@ -767,7 +770,7 @@ export default class ElementWrapper extends Wrapper {
? outro.expression.snippet ? outro.expression.snippet
: '{}'; : '{}';
const fn = `%transitions-${outro.name}`; const fn = `ctx.${outro.name}`;
block.builders.intro.addBlock(deindent` block.builders.intro.addBlock(deindent`
if (${outroName}) ${outroName}.abort(1); if (${outroName}) ${outroName}.abort(1);
@ -900,10 +903,10 @@ export default class ElementWrapper extends Wrapper {
const slot = this.attributes.find(attribute => attribute.name === 'slot'); const slot = this.attributes.find(attribute => attribute.name === 'slot');
if (slot) { if (slot) {
const prop = quotePropIfNecessary(slot.chunks[0].data); 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) { addCssClass(className = this.component.stylesheet.id) {

@ -92,7 +92,7 @@ export default class InlineComponentWrapper extends Wrapper {
componentInitProperties.push(`slots: { ${slots.join(', ')} }`); componentInitProperties.push(`slots: { ${slots.join(', ')} }`);
this.fragment.nodes.forEach((child: Wrapper) => { 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) { remount(name: string) {
return `${this.var}.$$mount(${name}._slotted.default, null);`; return `${this.var}.$$mount(${name}.$$slotted.default, null);`;
} }
} }

@ -49,7 +49,7 @@ export default class SlotWrapper extends Wrapper {
const content_name = block.getUniqueName(`slot_content_${sanitize(slotName)}`); const content_name = block.getUniqueName(`slot_content_${sanitize(slotName)}`);
const prop = quotePropIfNecessary(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'? // TODO can we use isDomNode instead of type === 'Element'?
const needsAnchorBefore = this.prev ? this.prev.node.type !== 'Element' : !parentNode; 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, // if the slot is unmounted, move nodes back into the document fragment,
// so that it can be reinserted later // 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 // be all fragments, derived from options.slots. Not === options.slots
const unmountLeadin = block.builders.destroy.toString() !== destroyBefore const unmountLeadin = block.builders.destroy.toString() !== destroyBefore
? `else` ? `else`

@ -62,6 +62,6 @@ export default class TextWrapper extends Wrapper {
} }
remount(name: string) { remount(name: string) {
return `@append(${name}._slotted.default, ${this.var});`; return `@append(${name}.$$slotted.default, ${this.var});`;
} }
} }

@ -62,6 +62,6 @@ export default class Tag extends Wrapper {
} }
remount(name: string) { remount(name: string) {
return `@append(${name}._slotted.default, ${this.var});`; return `@append(${name}.$$slotted.default, ${this.var});`;
} }
} }

@ -87,6 +87,6 @@ export default class Wrapper {
} }
remount(name: string) { remount(name: string) {
return `${this.var}.m(${name}._slotted.default, null);`; return `${this.var}.m(${name}.$$slotted.default, null);`;
} }
} }

@ -9,6 +9,8 @@ export class SvelteComponent {
this.$$onupdate = []; this.$$onupdate = [];
this.$$ondestroy = []; this.$$ondestroy = [];
this.$$slotted = options.slots;
set_current_component(this); set_current_component(this);
const [get_state, inject_props, inject_refs] = this.$$init( const [get_state, inject_props, inject_refs] = this.$$init(
key => this.$$make_dirty(key) key => this.$$make_dirty(key)

@ -89,7 +89,8 @@ export function wrapTransition(component, node, fn, params, intro) {
}, },
start(program) { 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.a = this.t;
program.delta = program.b - program.a; 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); 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) { if (!program.b && !program.invalidated) {
program.group.callbacks.push(() => { program.group.callbacks.push(() => {

@ -408,15 +408,28 @@ function readAttribute(parser: Parser, uniqueNames: Set<string>) {
const end = parser.index; const end = parser.index;
if (type) { if (type) {
name = name.slice(colon_index + 1); const directive_name = name.slice(colon_index + 1);
return { const directive = {
start, start,
end, end,
type, type,
name, name: directive_name
[type === 'Binding' ? 'value' : 'expression']: value[0] && value[0].expression
}; };
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 { return {

@ -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 { has(name: string): boolean {
return ( return (
this.declarations.has(name) || (this.parent && this.parent.has(name)) this.declarations.has(name) || (this.parent && this.parent.has(name))

@ -1,3 +1,7 @@
<script>
let input;
</script>
{#if visible} {#if visible}
<input ref:input autofocus> <input ref:input autofocus>
{/if} {/if}

@ -1,9 +1,8 @@
<script> <script>
export let dir; export let dir;
export let open = true; export let open = true;
export let items = [];
function items() { function get_items() {
return dir === 'a' return dir === 'a'
? [ ? [
{ {
@ -25,7 +24,7 @@
{#if open} {#if open}
<ul> <ul>
{#each items as item (item.filename)} {#each get_items() as item (item.filename)}
{#if item.isDir} {#if item.isDir}
<svelte:self dir={item.filename}/> <svelte:self dir={item.filename}/>
{:else} {:else}

@ -16,7 +16,7 @@ export default {
nestedTransitions: true, nestedTransitions: true,
test(assert, component, target, window, raf) { test(assert, component, target, window, raf) {
component.refs.folder.set({ open: false }); component.folder.open = false;
assert.htmlEqual(target.innerHTML, ` assert.htmlEqual(target.innerHTML, `
<li> <li>
<span>a</span> <span>a</span>

Loading…
Cancel
Save