buble
Version:
The blazing fast, batteries-included ES2015 compiler
56 lines (43 loc) • 1.44 kB
JavaScript
import Node from '../Node.js';
function normalise(str, removeTrailingWhitespace) {
if (removeTrailingWhitespace && /\n/.test(str)) {
str = str.replace(/[ \f\n\r\t\v]+$/, '');
}
str = str
.replace(/^\n\r?[ \f\n\r\t\v]+/, '') // remove leading newline + space
.replace(/[ \f\n\r\t\v]*\n\r?[ \f\n\r\t\v]*/gm, ' '); // replace newlines with spaces
// TODO prefer single quotes?
return JSON.stringify(str);
}
export default class JSXElement extends Node {
transpile(code, transforms) {
super.transpile(code, transforms);
const children = this.children.filter(child => {
if (child.type !== 'JSXText') return true;
// remove whitespace-only literals, unless on a single line
return /[^ \f\n\r\t\v]/.test(child.raw) || !/\n/.test(child.raw);
});
if (children.length) {
let c = (this.openingElement || this.openingFragment).end;
let i;
for (i = 0; i < children.length; i += 1) {
const child = children[i];
if (
child.type === 'JSXExpressionContainer' &&
child.expression.type === 'JSXEmptyExpression'
) {
// empty block is a no op
} else {
const tail =
code.original[c] === '\n' && child.type !== 'JSXText' ? '' : ' ';
code.appendLeft(c, `,${tail}`);
}
if (child.type === 'JSXText') {
const str = normalise(child.value, i === children.length - 1);
code.overwrite(child.start, child.end, str);
}
c = child.end;
}
}
}
}