pull/1367/head
Rich Harris 8 years ago
parent f8db2eee61
commit 662363cca2

@ -6,6 +6,7 @@ import addToSet from '../../utils/addToSet';
import { DomGenerator } from '../dom/index';
import Node from './shared/Node';
import Element from './Element';
import Text from './Text';
import Block from '../dom/Block';
import Expression from './shared/Expression';
@ -22,15 +23,29 @@ export default class Attribute extends Node {
compiler: DomGenerator;
parent: Element;
name: string;
isSpread: boolean;
isTrue: boolean;
isDynamic: boolean;
chunks: Node[];
expression?: Expression;
chunks: (Text | Expression)[];
dependencies: Set<string>;
expression: Node;
constructor(compiler, parent, scope, info) {
super(compiler, parent, scope, info);
if (info.type === 'Spread') {
this.name = null;
this.isSpread = true;
this.isTrue = false;
this.expression = new Expression(compiler, this, scope, info.expression);
this.dependencies = this.expression.dependencies;
this.chunks = null;
this.isDynamic = true; // TODO not necessarily
}
else {
this.name = info.name;
this.isTrue = info.value === true;
@ -47,12 +62,12 @@ export default class Attribute extends Node {
return expression;
});
// TODO this would be better, but it breaks some stuff
// this.isDynamic = this.dependencies.size > 0;
this.isDynamic = this.chunks.length === 1
? this.chunks[0].type !== 'Text'
: this.chunks.length > 1;
// TODO this would be better, but it breaks some stuff
// this.isDynamic = this.dependencies.size > 0;
}
}
getValue() {

@ -57,6 +57,7 @@ export default class Element extends Node {
break;
case 'Attribute':
case 'Spread':
// special case
if (node.name === 'xmlns') this.namespace = node.value[0].data;
@ -151,18 +152,6 @@ export default class Element extends Node {
block.outros += 1;
}
this.attributes.forEach(attribute => {
if (attribute.type === 'Attribute' && attribute.value !== true) {
// removed
} else {
if (this.parent) this.parent.cannotUseInnerHTML();
if (attribute.type === 'Spread') {
block.addDependencies(attribute.metadata.dependencies);
}
}
});
const valueAttribute = this.attributes.find((attribute: Attribute) => attribute.name === 'value');
if (this.name === 'textarea') {
@ -526,23 +515,20 @@ export default class Element extends Node {
this.attributes
.filter(attr => attr.type === 'Attribute' || attr.type === 'Spread')
.forEach(attr => {
if (attr.type === 'Attribute') {
const { dynamic, value, dependencies } = mungeAttribute(attr, block);
const condition = attr.dependencies.size > 0
? [...attr.dependencies].map(d => `changed.${d}`).join(' || ')
: null;
if (attr.isSpread) {
const { snippet, dependencies } = attr.expression;
const snippet = `{ ${quoteIfNecessary(attr.name)}: ${value} }`;
initialProps.push(snippet);
const condition = dependencies && dependencies.map(d => `changed.${d}`).join(' || ');
updates.push(condition ? `${condition} && ${snippet}` : snippet);
}
else {
block.contextualise(attr.expression); // TODO gah
const { snippet, dependencies } = attr.metadata;
} else {
const snippet = `{ ${quoteIfNecessary(attr.name)}: ${attr.getValue()} }`;
initialProps.push(snippet);
const condition = dependencies && dependencies.map(d => `changed.${d}`).join(' || ');
updates.push(condition ? `${condition} && ${snippet}` : snippet);
}
});

@ -14,8 +14,7 @@ type MungedAttribute = {
export default function mungeAttribute(attribute: Node, block: Block): MungedAttribute {
if (attribute.type === 'Spread') {
block.contextualise(attribute.expression); // TODO remove
const { dependencies, snippet } = attribute.metadata;
const { dependencies, snippet } = attribute.expression;
return {
spread: true,

@ -35,13 +35,12 @@ export default function visitElement(
appendTarget.slots[slotName] = '';
}
if (node.attributes.find(attr => attr.type === 'Spread')) {
if (node.attributes.find(attr => attr.isSpread)) {
// TODO dry this out
const args = [];
node.attributes.forEach((attribute: Node) => {
if (attribute.type === 'Spread') {
block.contextualise(attribute.expression);
args.push(attribute.metadata.snippet);
args.push(attribute.expression.snippet);
} else if (attribute.type === 'Attribute') {
if (attribute.name === 'value' && node.name === 'textarea') {
textareaContents = stringifyAttributeValue(block, attribute.value);
@ -53,8 +52,7 @@ export default function visitElement(
attribute.value[0].type !== 'Text'
) {
// a boolean attribute with one non-Text chunk
block.contextualise(attribute.value[0].expression);
args.push(`{ ${quoteIfNecessary(attribute.name)}: ${attribute.value[0].metadata.snippet} }`);
args.push(`{ ${quoteIfNecessary(attribute.name)}: ${attribute.value[0].expression.snippet} }`);
} else {
args.push(`{ ${quoteIfNecessary(attribute.name)}: \`${stringifyAttributeValue(block, attribute.value)}\` }`);
}

Loading…
Cancel
Save