diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 2f90806673..fae252d3f5 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -19,7 +19,7 @@ import add_to_set from '../../../utils/add_to_set'; import add_event_handlers from '../shared/add_event_handlers'; import add_actions from '../shared/add_actions'; 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 { is_head } from '../shared/is_head'; import { Identifier } from 'estree'; @@ -158,6 +158,12 @@ export default class ElementWrapper extends Wrapper { 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 => { if (attribute.name === 'slot') { // TODO make separate subclass for this? @@ -184,20 +190,17 @@ export default class ElementWrapper extends Wrapper { type: 'slot' }); - const lets = this.node.lets; + const { scope, lets } = this.node; const seen = new Set(lets.map(l => l.name.name)); (owner as unknown as InlineComponentWrapper).node.lets.forEach(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, { - block: child_block, - scope: this.node.scope, - fn - }); + (owner as unknown as InlineComponentWrapper).slots.set( + name, + get_slot_definition(child_block, scope, lets) + ); this.renderer.blocks.push(child_block); } diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index 155612e878..db9ecae392 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -9,44 +9,13 @@ import { b, x, p } from 'code-red'; import Attribute from '../../../nodes/Attribute'; import get_object from '../../../utils/get_object'; 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 TemplateScope from '../../../nodes/shared/TemplateScope'; 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 = 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; @@ -116,12 +85,7 @@ export default class InlineComponentWrapper extends Wrapper { this.renderer.blocks.push(default_slot); - this.slots.set('default', { - 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.slots.set('default', get_slot_definition(default_slot, this.node.scope, this.node.lets)); this.fragment = new FragmentWrapper(renderer, default_slot, node.children, this, strip_whitespace, next_sibling); const dependencies: Set = new Set(); diff --git a/src/compiler/compile/render_dom/wrappers/shared/get_context_merger.ts b/src/compiler/compile/render_dom/wrappers/shared/get_context_merger.ts deleted file mode 100644 index e6b4d9a420..0000000000 --- a/src/compiler/compile/render_dom/wrappers/shared/get_context_merger.ts +++ /dev/null @@ -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 = 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})`; -} \ No newline at end of file diff --git a/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts b/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts new file mode 100644 index 0000000000..170e9d87db --- /dev/null +++ b/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts @@ -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 = 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}` + }; +} \ No newline at end of file