start fixing slots

pull/3945/head
Rich Harris 6 years ago
parent 6c3c3bbf2a
commit 12b9733bbd

@ -167,6 +167,10 @@ export default class Renderer {
head = x`#ctx[${i}]`;
}
} else {
if (i === undefined) {
throw new Error(`attempted to reference unknown value`);
}
head = x`#ctx[${i}]`;
}

@ -191,7 +191,7 @@ export default class ElementWrapper extends Wrapper {
if (!seen.has(l.name.name)) lets.push(l);
});
const fn = get_context_merger(lets);
const fn = get_context_merger(this.renderer, lets);
(owner as unknown as InlineComponentWrapper).slots.set(name, {
block: child_block,

@ -73,6 +73,10 @@ export default class InlineComponentWrapper extends Wrapper {
};
if (this.node.children.length) {
this.node.lets.forEach(l => {
renderer.add_to_context(l.value.name, true);
});
const default_slot = block.child({
comment: create_debugging_comment(node, renderer.component),
name: renderer.component.get_unique_name(`create_default_slot`),
@ -81,7 +85,7 @@ export default class InlineComponentWrapper extends Wrapper {
this.renderer.blocks.push(default_slot);
const fn = get_context_merger(this.node.lets);
const fn = get_context_merger(this.renderer, this.node.lets);
this.slots.set('default', {
block: default_slot,

@ -66,7 +66,6 @@ export default class SlotWrapper extends Wrapper {
get_slot_changes_fn = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_changes`);
get_slot_context_fn = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_context`);
const context = get_slot_data(this.node.values);
const changes = x`{}` as ObjectExpression;
const dependencies = new Set();
@ -99,14 +98,9 @@ export default class SlotWrapper extends Wrapper {
}
});
const arg = dependencies.size > 0 && {
type: 'ObjectPattern',
properties: Array.from(dependencies).map(name => p`${name}`)
};
renderer.blocks.push(b`
const ${get_slot_changes_fn} = (${arg}) => (${changes});
const ${get_slot_context_fn} = (${arg}) => (${context});
const ${get_slot_changes_fn} = #changes => #changes;
const ${get_slot_context_fn} = #ctx => ${get_slot_data(block, this.node.values)};
`);
} else {
get_slot_changes_fn = 'null';

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

@ -1,26 +1,27 @@
import Attribute from '../nodes/Attribute';
import { p, x } from 'code-red';
import { string_literal } from './stringify';
import Block from '../render_dom/Block';
export default function get_slot_data(values: Map<string, Attribute>) {
export default function get_slot_data(block: Block, values: Map<string, Attribute>) {
return {
type: 'ObjectExpression',
properties: Array.from(values.values())
.filter(attribute => attribute.name !== 'name')
.map(attribute => {
const value = get_value(attribute);
const value = get_value(block, attribute);
return p`${attribute.name}: ${value}`;
})
};
}
// TODO fairly sure this is duplicated at least once
function get_value(attribute: Attribute) {
function get_value(block: Block, attribute: Attribute) {
if (attribute.is_true) return x`true`;
if (attribute.chunks.length === 0) return x`""`;
let value = attribute.chunks
.map(chunk => chunk.type === 'Text' ? string_literal(chunk.data) : chunk.node)
.map(chunk => chunk.type === 'Text' ? string_literal(chunk.data) : chunk.manipulate(block))
.reduce((lhs, rhs) => x`${lhs} + ${rhs}`);
if (attribute.chunks.length > 1 && attribute.chunks[0].type !== 'Text') {

@ -71,15 +71,15 @@ export function create_slot(definition, ctx, $$scope, fn) {
}
export function get_slot_context(definition, ctx, $$scope, fn) {
return definition[1]
? assign({}, assign($$scope.ctx, definition[1](fn ? fn(ctx) : {})))
return definition[1] && fn
? assign($$scope.ctx.slice(), definition[1](fn(ctx)))
: $$scope.ctx;
}
export function get_slot_changes(definition, $$scope, changed, fn) {
return definition[1]
? assign({}, assign($$scope.changed || {}, definition[1](fn ? fn(changed) : {})))
: $$scope.changed || {};
return definition[1] && fn
? $$scope.changed | definition[1](fn(changed))
: $$scope.changed;
}
export function exclude_internal_props(props) {

Loading…
Cancel
Save