Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normalize whitespace for transformed JSX code #970

Merged
merged 1 commit into from
Apr 4, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 25 additions & 25 deletions vendor/fbtransform/transforms/react.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ var renderXJSExpressionContainer =
var renderXJSLiteral = require('./xjs').renderXJSLiteral;
var quoteAttrName = require('./xjs').quoteAttrName;

var trimLeft = require('./xjs').trimLeft;

/**
* Customized desugar processor.
*
Expand Down Expand Up @@ -53,7 +55,7 @@ function visitReactTag(traverse, object, path, state) {
var nameObject = openingElement.name;
var attributesObject = openingElement.attributes;

utils.catchup(openingElement.range[0], state);
utils.catchup(openingElement.range[0], state, trimLeft);

if (nameObject.namespace) {
throw new Error(
Expand All @@ -68,44 +70,43 @@ function visitReactTag(traverse, object, path, state) {

utils.move(nameObject.range[1], state);

var hasAttributes = attributesObject.length;

// if we don't have any attributes, pass in null
if (attributesObject.length === 0) {
if (hasAttributes) {
utils.append('{', state);
} else {
utils.append('null', state);
}

// write attributes
attributesObject.forEach(function(attr, index) {
utils.catchup(attr.range[0], state);
if (attr.name.namespace) {
throw new Error(
'Namespace attributes are not supported. ReactJSX is not XML.');
}
var name = attr.name.name;
var isFirst = index === 0;
var isLast = index === attributesObject.length - 1;

if (isFirst) {
utils.append('{', state);
}

utils.catchup(attr.range[0], state, trimLeft);
utils.append(quoteAttrName(name), state);
utils.append(':', state);
utils.append(': ', state);

if (!attr.value) {
state.g.buffer += 'true';
state.g.position = attr.name.range[1];
if (!isLast) {
utils.append(',', state);
utils.append(', ', state);
}
} else {
utils.move(attr.name.range[1], state);
// Use catchupWhiteSpace to skip over the '=' in the attribute
utils.catchupWhiteSpace(attr.value.range[0], state);
// Use catchupNewlines to skip over the '=' in the attribute
utils.catchupNewlines(attr.value.range[0], state);
if (JSX_ATTRIBUTE_TRANSFORMS.hasOwnProperty(attr.name.name)) {
utils.append(JSX_ATTRIBUTE_TRANSFORMS[attr.name.name](attr), state);
utils.move(attr.value.range[1], state);
if (!isLast) {
utils.append(',', state);
utils.append(', ', state);
}
} else if (attr.value.type === Syntax.Literal) {
renderXJSLiteral(attr.value, isLast, state);
Expand All @@ -114,18 +115,18 @@ function visitReactTag(traverse, object, path, state) {
}
}

if (isLast) {
utils.append('}', state);
}

utils.catchup(attr.range[1], state);
utils.catchup(attr.range[1], state, trimLeft);
});

if (!openingElement.selfClosing) {
utils.catchup(openingElement.range[1] - 1, state);
utils.catchup(openingElement.range[1] - 1, state, trimLeft);
utils.move(openingElement.range[1], state);
}

if (hasAttributes) {
utils.append('}', state);
}

// filter out whitespace
var childrenToRender = object.children.filter(function(child) {
return !(child.type === Syntax.Literal
Expand All @@ -147,7 +148,7 @@ function visitReactTag(traverse, object, path, state) {
}

childrenToRender.forEach(function(child, index) {
utils.catchup(child.range[0], state);
utils.catchup(child.range[0], state, trimLeft);

var isLast = index >= lastRenderableIndex;

Expand All @@ -158,22 +159,21 @@ function visitReactTag(traverse, object, path, state) {
} else {
traverse(child, path, state);
if (!isLast) {
utils.append(',', state);
state.g.buffer = state.g.buffer.replace(/(\s*),$/, ',$1');
utils.append(', ', state);
}
}

utils.catchup(child.range[1], state);
utils.catchup(child.range[1], state, trimLeft);
});
}

if (openingElement.selfClosing) {
// everything up to />
utils.catchup(openingElement.range[1] - 2, state);
utils.catchup(openingElement.range[1] - 2, state, trimLeft);
utils.move(openingElement.range[1], state);
} else {
// everything up to </ sdflksjfd>
utils.catchup(object.closingElement.range[0], state);
utils.catchup(object.closingElement.range[0], state, trimLeft);
utils.move(object.closingElement.range[1], state);
}

Expand Down
22 changes: 15 additions & 7 deletions vendor/fbtransform/transforms/xjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,25 +180,27 @@ function renderXJSLiteral(object, isLast, state, start, end) {
trimmedLine = trimmedLine.replace(/[ ]+$/, '');
}

utils.append(line.match(/^[ \t]*/)[0], state);
if (!isFirstLine) {
utils.append(line.match(/^[ \t]*/)[0], state);
}

if (trimmedLine || isLastNonEmptyLine) {
utils.append(
JSON.stringify(trimmedLine) +
(!isLastNonEmptyLine ? "+' '+" : ''),
(!isLastNonEmptyLine ? " + ' ' +" : ''),
state);

if (isLastNonEmptyLine) {
if (end) {
utils.append(end, state);
}
if (!isLast) {
utils.append(',', state);
utils.append(', ', state);
}
}

// only restore tail whitespace if line had literals
if (trimmedLine) {
if (trimmedLine && !isLastLine) {
utils.append(line.match(/[ \t]*$/)[0], state);
}
}
Expand All @@ -215,14 +217,15 @@ function renderXJSExpressionContainer(traverse, object, isLast, path, state) {
// Plus 1 to skip `{`.
utils.move(object.range[0] + 1, state);
traverse(object.expression, path, state);

if (!isLast && object.expression.type !== Syntax.XJSEmptyExpression) {
// If we need to append a comma, make sure to do so after the expression.
utils.catchup(object.expression.range[1], state);
utils.append(',', state);
utils.catchup(object.expression.range[1], state, trimLeft);
utils.append(', ', state);
}

// Minus 1 to skip `}`.
utils.catchup(object.range[1] - 1, state);
utils.catchup(object.range[1] - 1, state, trimLeft);
utils.move(object.range[1], state);
return false;
}
Expand All @@ -235,7 +238,12 @@ function quoteAttrName(attr) {
return attr;
}

function trimLeft(value) {
return value.replace(/^[ ]+/, '');
}

exports.knownTags = knownTags;
exports.renderXJSExpressionContainer = renderXJSExpressionContainer;
exports.renderXJSLiteral = renderXJSLiteral;
exports.quoteAttrName = quoteAttrName;
exports.trimLeft = trimLeft;