fix some slot stuff

pull/3945/head
Rich Harris 6 years ago
parent c59c1530d6
commit b6d6053166

@ -19,7 +19,7 @@ import add_to_set from '../../../utils/add_to_set';
import add_event_handlers from '../shared/add_event_handlers'; import add_event_handlers from '../shared/add_event_handlers';
import add_actions from '../shared/add_actions'; import add_actions from '../shared/add_actions';
import create_debugging_comment from '../shared/create_debugging_comment'; import create_debugging_comment from '../shared/create_debugging_comment';
import { get_context_merger } from '../shared/get_context_merger'; import { get_slot_definition } from '../shared/get_slot_definition';
import bind_this from '../shared/bind_this'; import bind_this from '../shared/bind_this';
import { is_head } from '../shared/is_head'; import { is_head } from '../shared/is_head';
import { Identifier } from 'estree'; import { Identifier } from 'estree';
@ -158,6 +158,12 @@ export default class ElementWrapper extends Wrapper {
this.class_dependencies = []; this.class_dependencies = [];
if (this.node.children.length) {
this.node.lets.forEach(l => {
renderer.add_to_context((l.value || l.name).name, true);
});
}
this.attributes = this.node.attributes.map(attribute => { this.attributes = this.node.attributes.map(attribute => {
if (attribute.name === 'slot') { if (attribute.name === 'slot') {
// TODO make separate subclass for this? // TODO make separate subclass for this?
@ -184,20 +190,17 @@ export default class ElementWrapper extends Wrapper {
type: 'slot' type: 'slot'
}); });
const lets = this.node.lets; const { scope, lets } = this.node;
const seen = new Set(lets.map(l => l.name.name)); const seen = new Set(lets.map(l => l.name.name));
(owner as unknown as InlineComponentWrapper).node.lets.forEach(l => { (owner as unknown as InlineComponentWrapper).node.lets.forEach(l => {
if (!seen.has(l.name.name)) lets.push(l); if (!seen.has(l.name.name)) lets.push(l);
}); });
const fn = get_context_merger(this.renderer, lets); (owner as unknown as InlineComponentWrapper).slots.set(
name,
(owner as unknown as InlineComponentWrapper).slots.set(name, { get_slot_definition(child_block, scope, lets)
block: child_block, );
scope: this.node.scope,
fn
});
this.renderer.blocks.push(child_block); this.renderer.blocks.push(child_block);
} }

@ -9,44 +9,13 @@ import { b, x, p } from 'code-red';
import Attribute from '../../../nodes/Attribute'; import Attribute from '../../../nodes/Attribute';
import get_object from '../../../utils/get_object'; import get_object from '../../../utils/get_object';
import create_debugging_comment from '../shared/create_debugging_comment'; import create_debugging_comment from '../shared/create_debugging_comment';
import { get_context_merger } from '../shared/get_context_merger'; import { get_slot_definition } from '../shared/get_slot_definition';
import EachBlock from '../../../nodes/EachBlock'; import EachBlock from '../../../nodes/EachBlock';
import TemplateScope from '../../../nodes/shared/TemplateScope'; import TemplateScope from '../../../nodes/shared/TemplateScope';
import is_dynamic from '../shared/is_dynamic'; import is_dynamic from '../shared/is_dynamic';
import bind_this from '../shared/bind_this'; import bind_this from '../shared/bind_this';
import { Node, Identifier, ObjectExpression } from 'estree'; import { Node, Identifier, ObjectExpression } from 'estree';
import EventHandler from '../Element/EventHandler'; import EventHandler from '../Element/EventHandler';
import Let from '../../../nodes/Let';
function get_changes_merger(renderer: Renderer, lets: Let[]) {
if (lets.length === 0) return null;
const input = {
type: 'ObjectPattern',
properties: lets.map(l => ({
type: 'Property',
kind: 'init',
key: l.name,
value: l.value || l.name
}))
};
const names: Set<string> = new Set();
lets.forEach(l => {
l.names.forEach(name => {
names.add(name);
});
});
const expressions = Array.from(names).map(name => {
const i = renderer.context_lookup.get(name);
return x`${name} ? ${1 << i} : 0`;
});
const output = expressions.reduce((lhs, rhs) => x`${lhs} | ${rhs}`);
return x`(${input}) => (${output})`;
}
export default class InlineComponentWrapper extends Wrapper { export default class InlineComponentWrapper extends Wrapper {
var: Identifier; var: Identifier;
@ -116,12 +85,7 @@ export default class InlineComponentWrapper extends Wrapper {
this.renderer.blocks.push(default_slot); this.renderer.blocks.push(default_slot);
this.slots.set('default', { this.slots.set('default', get_slot_definition(default_slot, this.node.scope, this.node.lets));
block: default_slot,
scope: this.node.scope,
get_context: get_context_merger(this.renderer, this.node.lets),
get_changes: get_changes_merger(this.renderer, this.node.lets)
});
this.fragment = new FragmentWrapper(renderer, default_slot, node.children, this, strip_whitespace, next_sibling); this.fragment = new FragmentWrapper(renderer, default_slot, node.children, this, strip_whitespace, next_sibling);
const dependencies: Set<string> = new Set(); const dependencies: Set<string> = new Set();

@ -1,31 +0,0 @@
import Let from '../../../nodes/Let';
import { x, p } from 'code-red';
import Renderer from '../../Renderer';
export function get_context_merger(renderer: Renderer, lets: Let[]) {
if (lets.length === 0) return null;
const input = {
type: 'ObjectPattern',
properties: lets.map(l => ({
type: 'Property',
kind: 'init',
key: l.name,
value: l.value || l.name
}))
};
const names: Set<string> = new Set();
lets.forEach(l => {
l.names.forEach(name => {
names.add(name);
});
});
const output = {
type: 'ObjectExpression',
properties: Array.from(names).map(name => p`${renderer.context_lookup.get(name)}: ${name}`)
};
return x`(${input}) => (${output})`;
}

@ -0,0 +1,44 @@
import Let from '../../../nodes/Let';
import { x, p } from 'code-red';
import Block from '../../Block';
import TemplateScope from '../../../nodes/shared/TemplateScope';
export function get_slot_definition(block: Block, scope: TemplateScope, lets: Let[]) {
if (lets.length === 0) return { block, scope };
const input = {
type: 'ObjectPattern',
properties: lets.map(l => ({
type: 'Property',
kind: 'init',
key: l.name,
value: l.value || l.name
}))
};
const names: Set<string> = new Set();
lets.forEach(l => {
l.names.forEach(name => {
names.add(name);
});
});
const context = {
type: 'ObjectExpression',
properties: Array.from(names).map(name => p`${block.renderer.context_lookup.get(name)}: ${name}`)
};
const changes = Array.from(names)
.map(name => {
const i = block.renderer.context_lookup.get(name);
return x`${name} ? ${1 << i} : 0`;
})
.reduce((lhs, rhs) => x`${lhs} | ${rhs}`);
return {
block,
scope,
get_context: x`${input} => ${context}`,
get_changes: x`${input} => ${changes}`
};
}
Loading…
Cancel
Save