some slots and transitions stuff

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

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

@ -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) {

@ -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';

@ -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() {

@ -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]);
});
}`}

@ -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);`;
}
}

@ -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) {

@ -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);`;
}
}

@ -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`

@ -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});`;
}
}

@ -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});`;
}
}

@ -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);`;
}
}

@ -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)

@ -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(() => {

@ -408,15 +408,28 @@ function readAttribute(parser: Parser, uniqueNames: Set<string>) {
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 {

@ -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))

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

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

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

Loading…
Cancel
Save