diff --git a/src/dom/components/__tests__/ReactDOMTextarea-test.js b/src/dom/components/__tests__/ReactDOMTextarea-test.js index aaca8ea596b..70055adbb67 100644 --- a/src/dom/components/__tests__/ReactDOMTextarea-test.js +++ b/src/dom/components/__tests__/ReactDOMTextarea-test.js @@ -188,7 +188,7 @@ describe('ReactDOMTextarea', function() { expect(function() { ReactTestUtils.renderIntoDocument( - + ); }).toThrow(); diff --git a/vendor/fbtransform/transforms/react.js b/vendor/fbtransform/transforms/react.js index af5aa7dbedc..f3735a1bf92 100644 --- a/vendor/fbtransform/transforms/react.js +++ b/vendor/fbtransform/transforms/react.js @@ -50,6 +50,12 @@ var JSX_ATTRIBUTE_TRANSFORMS = { } }; +function isChildString(child) { + return child.type === Syntax.Literal || + child.type === Syntax.XJSExpressionContainer && + child.expression.raw && child.expression.raw.match(/^(|'[^']*'|"[^"]*")$/); +} + function visitReactTag(traverse, object, path, state) { var jsxObjIdent = utils.getDocblock(state).jsx; @@ -134,18 +140,23 @@ function visitReactTag(traverse, object, path, state) { if (childrenToRender.length > 0) { utils.append(', ', state); - object.children.forEach(function(child) { - if (child.type === Syntax.Literal && !child.value.match(/\S/)) { - return; - } + childrenToRender.forEach(function(child, index) { utils.catchup(child.range[0], state); - var isLast = child === childrenToRender[childrenToRender.length - 1]; + var isLast = index === childrenToRender.length - 1; if (child.type === Syntax.Literal) { - renderXJSLiteral(child, isLast, state); + var concat = !isLast && isChildString(childrenToRender[index + 1]); + + renderXJSLiteral(child, isLast, state, null, null, concat); } else if (child.type === Syntax.XJSExpressionContainer) { - renderXJSExpressionContainer(traverse, child, isLast, path, state); + var concat = !isLast && + isChildString(child) && + isChildString(childrenToRender[index + 1]); + + renderXJSExpressionContainer( + traverse, child, isLast, path, state, concat + ); } else { traverse(child, path, state); if (!isLast) { diff --git a/vendor/fbtransform/transforms/xjs.js b/vendor/fbtransform/transforms/xjs.js index faa9fb40f33..0fd4fbc6521 100644 --- a/vendor/fbtransform/transforms/xjs.js +++ b/vendor/fbtransform/transforms/xjs.js @@ -171,7 +171,7 @@ function trimWithSingleSpace(string) { * "line "+ * "line" */ -function renderXJSLiteral(object, isLast, state, start, end) { +function renderXJSLiteral(object, isLast, state, start, end, concat) { /** Added blank check filtering and triming*/ var trimmedChildValue = safeTrim(object.value); var hasFinalNewLine = false; @@ -253,7 +253,7 @@ function renderXJSLiteral(object, isLast, state, start, end) { // add comma before trailing whitespace if (!isLast) { - utils.append(',', state); + utils.append(concat ? '+' : ',', state); } // tail whitespace @@ -264,14 +264,16 @@ function renderXJSLiteral(object, isLast, state, start, end) { utils.move(object.range[1], state); } -function renderXJSExpressionContainer(traverse, object, isLast, path, state) { +function renderXJSExpressionContainer( + traverse, object, isLast, path, state, concat +) { // 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.append(concat ? '+' : ',', state); } // Minus 1 to skip `}`.