From 83be9297d514e8c3beca3c430ad7193f61a7aef5 Mon Sep 17 00:00:00 2001 From: Armand Abric Date: Sun, 8 Oct 2017 18:27:59 +0200 Subject: [PATCH] fix(formatting): trailling space Closes #135 BREAKING CHANGE: Trailling are now preserved. In some rare case, `react-element-to-jsx-string` failed to respect the JSX specs for the trailing space. Event is the space were in the final output. There were silentrly ignored by JSX parser. This commit fix this bug by protecting the trailing space in the output. If we take the JSX: ```jsx
foo bar baz
``` Before it was converted to (the trailing space are replace by `*` for the readability): ```html
foo* bar *baz
``` Now there are preserved: ```html
foo{' '} bar {' '}baz
``` --- src/formatter/formatProp.js | 2 +- src/formatter/formatTreeNode.js | 17 ++++++++++++++++- src/index.spec.js | 20 +++++++++++++++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/formatter/formatProp.js b/src/formatter/formatProp.js index 77a0f5a87..9fcac3c01 100644 --- a/src/formatter/formatProp.js +++ b/src/formatter/formatProp.js @@ -39,7 +39,7 @@ export default ( formattedPropValue === '{false}' && !hasDefaultValue ) { - // If a boolean is false an is not different from it's default, we do not render the attribute + // If a boolean is false and not different from it's default, we do not render the attribute attributeFormattedInline = ''; attributeFormattedMultiline = ''; } else if (useBooleanShorthandSyntax && formattedPropValue === '{true}') { diff --git a/src/formatter/formatTreeNode.js b/src/formatter/formatTreeNode.js index cf2328435..03ea5a091 100644 --- a/src/formatter/formatTreeNode.js +++ b/src/formatter/formatTreeNode.js @@ -16,6 +16,19 @@ const escape = (s: string) => { return `{\`${s}\`}`; }; +const preserveTrailingSpace = (s: string) => { + let result = s; + if (result.endsWith(' ')) { + result = result.replace(/^(\S*)(\s*)$/, "$1{'$2'}"); + } + + if (result.startsWith(' ')) { + result = result.replace(/^(\s*)(\S*)$/, "{'$1'}$2"); + } + + return result; +}; + export default ( node: TreeNode, inline: boolean, @@ -27,7 +40,9 @@ export default ( } if (node.type === 'string') { - return node.value ? escape(String(node.value)) : ''; + return node.value + ? `${preserveTrailingSpace(escape(String(node.value)))}` + : ''; } if (node.type === 'ReactElement') { diff --git a/src/index.spec.js b/src/index.spec.js index 695d8851b..1b473b007 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -556,6 +556,22 @@ describe('reactElementToJSXString(ReactElement)', () => { ); }); + it('reactElementToJSXString(
\nfoo bar baz\n
)', () => { + expect( + reactElementToJSXString( +
+ foo bar baz +
+ ) + ).toEqual(`
+ foo{' '} + + bar + + {' '}baz +
`); + }); + it('reactElementToJSXString(
', () => { expect(reactElementToJSXString(
)).toEqual( `
{ it('reactElementToJSXString(
{false}
)', () => { expect(reactElementToJSXString(
{false}
)).toEqual( - '
\n \n
' + `
+ {' '} +
` ); });