mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
[CS2] CSX spread attributes: <div {props…} /> (#4607)
* CSX spread attributes: <div {props...} /> * whitespace cleanup * Style * valid CSX attributes * added comments; cleanup * Fixed allowed CSX properties. * Cleanup * Typo * Improved RegEx * Reworked CSX attributes * small fix for CSX attribute validation * cleanup * tests * fix nested assignement; remove unused variable * cleanup; improve tests * fix esoteric case; improve tracking nested splats in CSX tag
This commit is contained in:
parent
a118ec7cc9
commit
cbf035fca9
7 changed files with 351 additions and 420 deletions
|
@ -1670,7 +1670,7 @@
|
|||
}
|
||||
|
||||
compileCSX(o) {
|
||||
var attributes, content, fragments, tag;
|
||||
var attr, attrProps, attributes, content, fragments, j, len1, obj, ref1, tag;
|
||||
[attributes, content] = this.args;
|
||||
attributes.base.csx = true;
|
||||
if (content != null) {
|
||||
|
@ -1678,7 +1678,23 @@
|
|||
}
|
||||
fragments = [this.makeCode('<')];
|
||||
fragments.push(...(tag = this.variable.compileToFragments(o, LEVEL_ACCESS)));
|
||||
fragments.push(...attributes.compileToFragments(o, LEVEL_PAREN));
|
||||
if (attributes.base instanceof Arr) {
|
||||
ref1 = attributes.base.objects;
|
||||
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||
obj = ref1[j];
|
||||
attr = obj.base;
|
||||
attrProps = (attr != null ? attr.properties : void 0) || [];
|
||||
// Catch invalid CSX attributes: <div {a:"b", props} {props} "value" />
|
||||
if (!(attr instanceof Obj || attr instanceof IdentifierLiteral) || (attr instanceof Obj && !attr.generated && (attrProps.length > 1 || !(attrProps[0] instanceof Splat)))) {
|
||||
obj.error("Unexpected token. Allowed CSX attributes are: id=\"val\", src={source}, {props...} or attribute.");
|
||||
}
|
||||
if (obj.base instanceof Obj) {
|
||||
obj.base.csx = true;
|
||||
}
|
||||
fragments.push(this.makeCode(' '));
|
||||
fragments.push(...obj.compileToFragments(o, LEVEL_PAREN));
|
||||
}
|
||||
}
|
||||
if (content) {
|
||||
fragments.push(this.makeCode('>'));
|
||||
fragments.push(...content.compileNode(o, LEVEL_LIST));
|
||||
|
@ -2109,12 +2125,16 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
if (this.hasSplat()) {
|
||||
if (this.hasSplat() && !this.csx) {
|
||||
// Object spread properties. https://github.com/tc39/proposal-object-rest-spread/blob/master/Spread.md
|
||||
return this.compileSpread(o);
|
||||
}
|
||||
idt = o.indent += TAB;
|
||||
lastNode = this.lastNode(this.properties);
|
||||
if (this.csx) {
|
||||
// CSX attributes <div id="val" attr={aaa} {props...} />
|
||||
return this.compileCSXAttributes(o);
|
||||
}
|
||||
// If this object is the left-hand side of an assignment, all its children
|
||||
// are too.
|
||||
if (this.lhs) {
|
||||
|
@ -2136,7 +2156,7 @@
|
|||
ref1 = this.properties;
|
||||
for (l = 0, len3 = ref1.length; l < len3; l++) {
|
||||
prop = ref1[l];
|
||||
if (prop instanceof Assign && prop.context === 'object' && !this.csx) {
|
||||
if (prop instanceof Assign && prop.context === 'object') {
|
||||
isCompact = false;
|
||||
}
|
||||
}
|
||||
|
@ -2144,7 +2164,7 @@
|
|||
answer.push(this.makeCode(isCompact ? '' : '\n'));
|
||||
for (i = q = 0, len4 = props.length; q < len4; i = ++q) {
|
||||
prop = props[i];
|
||||
join = i === props.length - 1 ? '' : isCompact && this.csx ? ' ' : isCompact ? ', ' : prop === lastNode || this.csx ? '\n' : ',\n';
|
||||
join = i === props.length - 1 ? '' : isCompact ? ', ' : prop === lastNode ? '\n' : ',\n';
|
||||
indent = isCompact ? '' : idt;
|
||||
key = prop instanceof Assign && prop.context === 'object' ? prop.variable : prop instanceof Assign ? (!this.lhs ? prop.operatorToken.error(`unexpected ${prop.operatorToken.value}`) : void 0, prop.variable) : prop;
|
||||
if (key instanceof Value && key.hasProperties()) {
|
||||
|
@ -2168,21 +2188,13 @@
|
|||
if (indent) {
|
||||
answer.push(this.makeCode(indent));
|
||||
}
|
||||
if (this.csx) {
|
||||
prop.csx = true;
|
||||
}
|
||||
if (this.csx && i === 0) {
|
||||
answer.push(this.makeCode(' '));
|
||||
}
|
||||
answer.push(...prop.compileToFragments(o, LEVEL_TOP));
|
||||
if (join) {
|
||||
answer.push(this.makeCode(join));
|
||||
}
|
||||
}
|
||||
answer.push(this.makeCode(isCompact ? '' : `\n${this.tab}`));
|
||||
if (!this.csx) {
|
||||
answer = this.wrapInBraces(answer);
|
||||
}
|
||||
answer = this.wrapInBraces(answer);
|
||||
if (this.front) {
|
||||
return this.wrapInParentheses(answer);
|
||||
} else {
|
||||
|
@ -2256,6 +2268,27 @@
|
|||
return (new Call(new Literal('Object.assign'), slices)).compileToFragments(o);
|
||||
}
|
||||
|
||||
compileCSXAttributes(o) {
|
||||
var answer, i, j, join, len1, prop, props;
|
||||
props = this.properties;
|
||||
answer = [];
|
||||
for (i = j = 0, len1 = props.length; j < len1; i = ++j) {
|
||||
prop = props[i];
|
||||
prop.csx = true;
|
||||
join = i === props.length - 1 ? '' : ' ';
|
||||
if (prop instanceof Splat) {
|
||||
prop = new Literal(`{${prop.compile(o)}}`);
|
||||
}
|
||||
answer.push(...prop.compileToFragments(o, LEVEL_TOP));
|
||||
answer.push(this.makeCode(join));
|
||||
}
|
||||
if (this.front) {
|
||||
return this.wrapInParentheses(answer);
|
||||
} else {
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Obj.prototype.children = ['properties'];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue