mirror of https://github.com/sveltejs/svelte
parent
30595f4ee5
commit
2bb0be68d5
@ -1,103 +1,89 @@
|
|||||||
import { b, x } from 'code-red';
|
import { b, x } from 'code-red';
|
||||||
import Component from '../../../Component';
|
import { compare_node } from '../../../utils/compare_node.js';
|
||||||
import Block from '../../Block';
|
|
||||||
import BindingWrapper from '../Element/Binding';
|
|
||||||
import { Identifier } from 'estree';
|
|
||||||
import { compare_node } from '../../../utils/compare_node';
|
|
||||||
|
|
||||||
export default function bind_this(
|
/**
|
||||||
component: Component,
|
* @param {import('../../../Component.js').default} component
|
||||||
block: Block,
|
* @param {import('../../Block.js').default} block
|
||||||
binding: BindingWrapper,
|
* @param {import('../Element/Binding.js').default} binding
|
||||||
variable: Identifier
|
* @param {import('estree').Identifier} variable
|
||||||
) {
|
*/
|
||||||
const fn = component.get_unique_name(`${variable.name}_binding`);
|
export default function bind_this(component, block, binding, variable) {
|
||||||
|
const fn = component.get_unique_name(`${variable.name}_binding`);
|
||||||
block.renderer.add_to_context(fn.name);
|
block.renderer.add_to_context(fn.name);
|
||||||
const callee = block.renderer.reference(fn.name);
|
const callee = block.renderer.reference(fn.name);
|
||||||
|
const { contextual_dependencies, mutation } = binding.handler;
|
||||||
const { contextual_dependencies, mutation } = binding.handler;
|
const dependencies = binding.get_update_dependencies();
|
||||||
const dependencies = binding.get_update_dependencies();
|
const body = b `
|
||||||
|
|
||||||
const body = b`
|
|
||||||
${mutation}
|
${mutation}
|
||||||
${Array.from(dependencies)
|
${Array.from(dependencies)
|
||||||
.filter((dep) => dep[0] !== '$')
|
.filter((dep) => dep[0] !== '$')
|
||||||
.filter((dep) => !contextual_dependencies.has(dep))
|
.filter((dep) => !contextual_dependencies.has(dep))
|
||||||
.map((dep) => b`${block.renderer.invalidate(dep)};`)}
|
.map((dep) => b `${block.renderer.invalidate(dep)};`)}
|
||||||
`;
|
`;
|
||||||
|
if (contextual_dependencies.size) {
|
||||||
|
|
||||||
if (contextual_dependencies.size) {
|
/** @type {import('estree').Identifier[]} */
|
||||||
const params: Identifier[] = Array.from(contextual_dependencies).map((name) => ({
|
const params = Array.from(contextual_dependencies).map((name) => ({
|
||||||
type: 'Identifier',
|
type: 'Identifier',
|
||||||
name
|
name
|
||||||
}));
|
}));
|
||||||
component.partly_hoisted.push(b`
|
component.partly_hoisted.push(b `
|
||||||
function ${fn}($$value, ${params}) {
|
function ${fn}($$value, ${params}) {
|
||||||
@binding_callbacks[$$value ? 'unshift' : 'push'](() => {
|
@binding_callbacks[$$value ? 'unshift' : 'push'](() => {
|
||||||
${body}
|
${body}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
const alias_map = new Map();
|
||||||
const alias_map = new Map();
|
const args = [];
|
||||||
const args = [];
|
for (let id of params) {
|
||||||
for (let id of params) {
|
const value = block.renderer.reference(id.name);
|
||||||
const value = block.renderer.reference(id.name);
|
let found = false;
|
||||||
let found = false;
|
if (block.variables.has(id.name)) {
|
||||||
if (block.variables.has(id.name)) {
|
let alias = id.name;
|
||||||
let alias = id.name;
|
for (let i = 1; block.variables.has(alias) && !compare_node(block.variables.get(alias).init, value); alias = `${id.name}_${i++}`)
|
||||||
for (
|
;
|
||||||
let i = 1;
|
alias_map.set(alias, id.name);
|
||||||
block.variables.has(alias) && !compare_node(block.variables.get(alias).init, value);
|
id = { type: 'Identifier', name: alias };
|
||||||
alias = `${id.name}_${i++}`
|
found = block.variables.has(alias);
|
||||||
);
|
}
|
||||||
alias_map.set(alias, id.name);
|
args.push(id);
|
||||||
id = { type: 'Identifier', name: alias };
|
if (!found) {
|
||||||
found = block.variables.has(alias);
|
block.add_variable(id, value);
|
||||||
}
|
}
|
||||||
args.push(id);
|
}
|
||||||
if (!found) {
|
const assign = block.get_unique_name(`assign_${variable.name}`);
|
||||||
block.add_variable(id, value);
|
const unassign = block.get_unique_name(`unassign_${variable.name}`);
|
||||||
}
|
block.chunks.init.push(b `
|
||||||
}
|
|
||||||
|
|
||||||
const assign = block.get_unique_name(`assign_${variable.name}`);
|
|
||||||
const unassign = block.get_unique_name(`unassign_${variable.name}`);
|
|
||||||
|
|
||||||
block.chunks.init.push(b`
|
|
||||||
const ${assign} = () => ${callee}(${variable}, ${args});
|
const ${assign} = () => ${callee}(${variable}, ${args});
|
||||||
const ${unassign} = () => ${callee}(null, ${args});
|
const ${unassign} = () => ${callee}(null, ${args});
|
||||||
`);
|
`);
|
||||||
|
const condition = Array.from(args)
|
||||||
const condition = Array.from(args)
|
.map((name) => x `${name} !== ${block.renderer.reference(alias_map.get(name.name) || name.name)}`)
|
||||||
.map(
|
.reduce((lhs, rhs) => x `${lhs} || ${rhs}`);
|
||||||
(name) => x`${name} !== ${block.renderer.reference(alias_map.get(name.name) || name.name)}`
|
// we push unassign and unshift assign so that references are
|
||||||
)
|
// nulled out before they're created, to avoid glitches
|
||||||
.reduce((lhs, rhs) => x`${lhs} || ${rhs}`);
|
// with shifting indices
|
||||||
|
block.chunks.update.push(b `
|
||||||
// we push unassign and unshift assign so that references are
|
|
||||||
// nulled out before they're created, to avoid glitches
|
|
||||||
// with shifting indices
|
|
||||||
block.chunks.update.push(b`
|
|
||||||
if (${condition}) {
|
if (${condition}) {
|
||||||
${unassign}();
|
${unassign}();
|
||||||
${args.map((a) => b`${a} = ${block.renderer.reference(alias_map.get(a.name) || a.name)}`)};
|
${args.map((a) => b `${a} = ${block.renderer.reference(alias_map.get(a.name) || a.name)}`)};
|
||||||
${assign}();
|
${assign}();
|
||||||
}`);
|
}`);
|
||||||
|
block.chunks.destroy.push(b `${unassign}();`);
|
||||||
block.chunks.destroy.push(b`${unassign}();`);
|
return b `${assign}();`;
|
||||||
return b`${assign}();`;
|
}
|
||||||
}
|
component.partly_hoisted.push(b `
|
||||||
|
|
||||||
component.partly_hoisted.push(b`
|
|
||||||
function ${fn}($$value) {
|
function ${fn}($$value) {
|
||||||
@binding_callbacks[$$value ? 'unshift' : 'push'](() => {
|
@binding_callbacks[$$value ? 'unshift' : 'push'](() => {
|
||||||
${body}
|
${body}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
block.chunks.destroy.push(b `${callee}(null);`);
|
||||||
block.chunks.destroy.push(b`${callee}(null);`);
|
return b `${callee}(${variable});`;
|
||||||
return b`${callee}(${variable});`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in new issue