pull/3945/head
Rich Harris 6 years ago
parent b7634b8d6b
commit 0f7a42d92a

@ -138,11 +138,15 @@ export default class Renderer {
.reduce((lhs, rhs) => x`${lhs}, ${rhs}}`);
}
changed(names, needs_update = false) {
const bitmask = names.reduce((bits, name) => {
get_bitmask(names) {
return names.reduce((bits, name) => {
const bit = 1 << this.context_lookup.get(name);
return bits | bit;
}, 0);
}
changed(names, needs_update = false) {
const bitmask = this.get_bitmask(names);
return needs_update
? x`(#changed = $$self.$$.dirty) & ${bitmask}`

@ -16,10 +16,41 @@ import is_dynamic from '../shared/is_dynamic';
import bind_this from '../shared/bind_this';
import { Node, Identifier, ObjectExpression } from 'estree';
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 {
var: Identifier;
slots: Map<string, { block: Block; scope: TemplateScope; fn?: Node }> = new Map();
slots: Map<string, { block: Block; scope: TemplateScope; get_context?: Node, get_changes?: Node }> = new Map();
node: InlineComponent;
fragment: FragmentWrapper;
@ -74,7 +105,7 @@ export default class InlineComponentWrapper extends Wrapper {
if (this.node.children.length) {
this.node.lets.forEach(l => {
renderer.add_to_context(l.value.name, true);
renderer.add_to_context((l.value || l.name).name, true);
});
const default_slot = block.child({
@ -85,12 +116,11 @@ export default class InlineComponentWrapper extends Wrapper {
this.renderer.blocks.push(default_slot);
const fn = get_context_merger(this.renderer, this.node.lets);
this.slots.set('default', {
block: default_slot,
scope: this.node.scope,
fn
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);
@ -133,7 +163,7 @@ export default class InlineComponentWrapper extends Wrapper {
? [
p`$$slots: {
${Array.from(this.slots).map(([name, slot]) => {
return p`${name}: [${slot.block.name}, ${slot.fn || null}]`;
return p`${name}: [${slot.block.name}, ${slot.get_context || null}, ${slot.get_changes || null}]`;
})}
}`,
p`$$scope: {

@ -90,16 +90,13 @@ export default class SlotWrapper extends Wrapper {
});
if (dynamic_dependencies.length > 0) {
const expression = dynamic_dependencies
.map(name => ({ type: 'Identifier', name } as any))
.reduce((lhs, rhs) => x`${lhs} || ${rhs}`);
changes.properties.push(p`${attribute.name}: ${expression}`);
const bitmask = renderer.get_bitmask(dynamic_dependencies);
changes.properties.push(p`${attribute.name}: #changes & ${bitmask}`);
}
});
renderer.blocks.push(b`
const ${get_slot_changes_fn} = #changes => #changes;
const ${get_slot_changes_fn} = #changes => ${changes};
const ${get_slot_context_fn} = #ctx => ${get_slot_data(block, this.node.values)};
`);
} else {

@ -77,8 +77,8 @@ export function get_slot_context(definition, ctx, $$scope, fn) {
}
export function get_slot_changes(definition, $$scope, changed, fn) {
return definition[1] && fn
? $$scope.changed | definition[1](fn(changed))
return definition[2] && fn
? $$scope.changed | definition[2](fn(changed))
: $$scope.changed;
}

Loading…
Cancel
Save