mirror of https://github.com/sveltejs/svelte
parent
3f32be8c04
commit
f6f8f66c90
@ -1,200 +0,0 @@
|
|||||||
import deindent from '../../utils/deindent';
|
|
||||||
import { DomGenerator } from '../dom/index';
|
|
||||||
import Node from './shared/Node';
|
|
||||||
import Element from './Element';
|
|
||||||
import Block from '../dom/Block';
|
|
||||||
|
|
||||||
export default class Spread {
|
|
||||||
type: 'Spread';
|
|
||||||
start: number;
|
|
||||||
end: number;
|
|
||||||
|
|
||||||
generator: DomGenerator;
|
|
||||||
parent: Element;
|
|
||||||
expression: Node;
|
|
||||||
|
|
||||||
metadata: {
|
|
||||||
dependencies: string[];
|
|
||||||
snippet: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor({
|
|
||||||
generator,
|
|
||||||
expression,
|
|
||||||
parent
|
|
||||||
}: {
|
|
||||||
generator: DomGenerator,
|
|
||||||
expression: Node,
|
|
||||||
parent: Element
|
|
||||||
}) {
|
|
||||||
this.type = 'Spread';
|
|
||||||
this.generator = generator;
|
|
||||||
this.parent = parent;
|
|
||||||
|
|
||||||
this.expression = expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderForElement(block: Block) {
|
|
||||||
const node = this.parent;
|
|
||||||
|
|
||||||
const { expression } = this;
|
|
||||||
const { indexes } = block.contextualise(expression);
|
|
||||||
const { dependencies, snippet } = this.metadata;
|
|
||||||
|
|
||||||
const value = snippet;
|
|
||||||
|
|
||||||
const hasChangeableIndex = Array.from(indexes).some(index => block.changeableIndexes.get(index));
|
|
||||||
|
|
||||||
const shouldCache = (
|
|
||||||
expression.type !== 'Identifier' ||
|
|
||||||
block.contexts.has(expression.name) ||
|
|
||||||
hasChangeableIndex
|
|
||||||
);
|
|
||||||
|
|
||||||
const last = shouldCache && block.getUniqueName(`${node.var}_spread_value`);
|
|
||||||
|
|
||||||
if (shouldCache) block.addVariable(last);
|
|
||||||
|
|
||||||
const init = shouldCache ? `${last} = ${value}` : value;
|
|
||||||
|
|
||||||
const activeKeys = block.getUniqueName(`${node.var}_spread_keys`);
|
|
||||||
block.addVariable(activeKeys, '{}');
|
|
||||||
|
|
||||||
const changes = block.getUniqueName(`${node.var}_spread_changes`);
|
|
||||||
|
|
||||||
const hasNamedAttributes = node.attributes.length;
|
|
||||||
const namedAttributes = block.getUniqueName(`${node.var}_attributes`);
|
|
||||||
|
|
||||||
if (hasNamedAttributes) {
|
|
||||||
block.builders.init.addBlock(deindent`
|
|
||||||
var ${namedAttributes} = [${node.attributes.map(attr => `'${attr.name}'`).join(', ')}];
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
|
|
||||||
block.builders.hydrate.addBlock(deindent`
|
|
||||||
var ${changes} = ${init};
|
|
||||||
for (var key in ${changes}) {
|
|
||||||
${hasNamedAttributes ? `if (${namedAttributes}.indexOf(key) !== -1) continue;` : ''}
|
|
||||||
|
|
||||||
@setAttribute(${node.var}, key, ${changes}[key]);
|
|
||||||
${activeKeys}[key] = true;
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
|
|
||||||
if (dependencies.length || hasChangeableIndex) {
|
|
||||||
const changedCheck = (
|
|
||||||
( block.hasOutroMethod ? `#outroing || ` : '' ) +
|
|
||||||
dependencies.map(dependency => `changed.${dependency}`).join(' || ')
|
|
||||||
);
|
|
||||||
|
|
||||||
const updateCachedValue = `${last} !== (${last} = ${value})`;
|
|
||||||
|
|
||||||
const condition = shouldCache ?
|
|
||||||
( dependencies.length ? `(${changedCheck}) && ${updateCachedValue}` : updateCachedValue ) :
|
|
||||||
changedCheck;
|
|
||||||
|
|
||||||
const oldKeys = block.getUniqueName(`${node.var}_spread_keys_old`);
|
|
||||||
|
|
||||||
const updater = deindent`
|
|
||||||
var ${oldKeys} = ${activeKeys};
|
|
||||||
${activeKeys} = {};
|
|
||||||
|
|
||||||
var ${changes} = ${shouldCache ? last : value};
|
|
||||||
for (var key in ${changes}) {
|
|
||||||
${hasNamedAttributes ? `if (${namedAttributes}.indexOf(key) !== -1) continue;` : ''}
|
|
||||||
|
|
||||||
@setAttribute(${node.var}, key, ${changes}[key]);
|
|
||||||
|
|
||||||
${activeKeys}[key] = true;
|
|
||||||
delete ${oldKeys}[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var key in ${oldKeys}) {
|
|
||||||
@removeAttribute(${node.var}, key);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
block.builders.update.addConditional(
|
|
||||||
condition,
|
|
||||||
updater
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderForComponent(block: Block, updates: string[]) {
|
|
||||||
const node = this.parent;
|
|
||||||
|
|
||||||
|
|
||||||
const { expression } = this;
|
|
||||||
const { indexes } = block.contextualise(expression);
|
|
||||||
const { dependencies, snippet } = this.metadata;
|
|
||||||
|
|
||||||
const value = snippet;
|
|
||||||
|
|
||||||
const hasChangeableIndex = Array.from(indexes).some(index => block.changeableIndexes.get(index));
|
|
||||||
|
|
||||||
const shouldCache = (
|
|
||||||
expression.type !== 'Identifier' ||
|
|
||||||
block.contexts.has(expression.name) ||
|
|
||||||
hasChangeableIndex
|
|
||||||
);
|
|
||||||
|
|
||||||
const last = shouldCache && block.getUniqueName(`${node.var}_spread_value`);
|
|
||||||
|
|
||||||
if (shouldCache) block.addVariable(last);
|
|
||||||
|
|
||||||
const init = shouldCache ? `${last} = ${value}` : value;
|
|
||||||
|
|
||||||
const activeKeys = block.getUniqueName(`${node.var}_spread_keys`);
|
|
||||||
block.addVariable(activeKeys, '{}');
|
|
||||||
|
|
||||||
const changes = block.getUniqueName(`${node.var}_spread_changes`);
|
|
||||||
|
|
||||||
const hasNamedAttributes = node.attributes.length;
|
|
||||||
const namedAttributes = block.getUniqueName(`${node.var}_attributes`);
|
|
||||||
|
|
||||||
if (hasNamedAttributes) {
|
|
||||||
block.builders.init.addBlock(deindent`
|
|
||||||
var ${namedAttributes} = [${node.attributes.map(attr => `'${attr.name}'`).join(', ')}];
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dependencies.length || hasChangeableIndex) {
|
|
||||||
const changedCheck = (
|
|
||||||
( block.hasOutroMethod ? `#outroing || ` : '' ) +
|
|
||||||
dependencies.map(dependency => `changed.${dependency}`).join(' || ')
|
|
||||||
);
|
|
||||||
|
|
||||||
const updateCachedValue = `${last} !== (${last} = ${value})`;
|
|
||||||
|
|
||||||
const condition = shouldCache ?
|
|
||||||
( dependencies.length ? `(${changedCheck}) && ${updateCachedValue}` : updateCachedValue ) :
|
|
||||||
changedCheck;
|
|
||||||
|
|
||||||
const oldKeys = block.getUniqueName(`${node.var}_spread_keys_old`);
|
|
||||||
|
|
||||||
updates.push(deindent`
|
|
||||||
if (${condition}) {
|
|
||||||
var ${oldKeys} = ${activeKeys};
|
|
||||||
${activeKeys} = {};
|
|
||||||
|
|
||||||
var ${changes} = ${shouldCache ? last : value};
|
|
||||||
for (var key in ${changes}) {
|
|
||||||
${hasNamedAttributes ? `if (${namedAttributes}.indexOf(key) !== -1) continue;` : ''}
|
|
||||||
|
|
||||||
${node.var}_changes[key] = ${changes}[key];
|
|
||||||
|
|
||||||
${activeKeys}[key] = true;
|
|
||||||
delete ${oldKeys}[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var key in ${oldKeys}) {
|
|
||||||
${node.var}_changes[key] = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in new issue