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}}`); .reduce((lhs, rhs) => x`${lhs}, ${rhs}}`);
} }
changed(names, needs_update = false) { get_bitmask(names) {
const bitmask = names.reduce((bits, name) => { return names.reduce((bits, name) => {
const bit = 1 << this.context_lookup.get(name); const bit = 1 << this.context_lookup.get(name);
return bits | bit; return bits | bit;
}, 0); }, 0);
}
changed(names, needs_update = false) {
const bitmask = this.get_bitmask(names);
return needs_update return needs_update
? x`(#changed = $$self.$$.dirty) & ${bitmask}` ? x`(#changed = $$self.$$.dirty) & ${bitmask}`

@ -16,10 +16,41 @@ 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;
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; node: InlineComponent;
fragment: FragmentWrapper; fragment: FragmentWrapper;
@ -74,7 +105,7 @@ export default class InlineComponentWrapper extends Wrapper {
if (this.node.children.length) { if (this.node.children.length) {
this.node.lets.forEach(l => { 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({ const default_slot = block.child({
@ -85,12 +116,11 @@ export default class InlineComponentWrapper extends Wrapper {
this.renderer.blocks.push(default_slot); this.renderer.blocks.push(default_slot);
const fn = get_context_merger(this.renderer, this.node.lets);
this.slots.set('default', { this.slots.set('default', {
block: default_slot, block: default_slot,
scope: this.node.scope, 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); 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: { p`$$slots: {
${Array.from(this.slots).map(([name, slot]) => { ${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: { p`$$scope: {

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

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

Loading…
Cancel
Save