Repository: i18next/i18next-parser
Pull request #254 (2020-12-17 17:47:09)

Outputting autoclosed tags when there's no child content
Outputting stuff like `<br></br>` is creating issues in react when `transSupportBasicHtmlNodes` is `true`

### Why am I submitting this PR

When parsing autoclosed tags and having `transSupportBasicHtmlNodes = true` the parser outputs the not autoclosed version oh the tag, causing exceptions in react

### Does it fix an existing ticket?

No 

### Checklist

- [X] only relevant code is changed (make a diff before you submit the PR)
- [x] tests are included and pass (see [details here](https://github.com/i18next/i18next-parser/blob/master/docs/development.md#tests))
- [x] documentation is changed or added


karellm: If you open a PR, you should add a test that explain that change. Plus your changes are breaking the test suite. Please fix this if you want me to review and merge it.
rformato: Thanks @karellm, I had left the PR in draft because it was not ready for review, nevertheless you checked it the same, which is great, thanks for your work. I can see the tests failing now, I'll check them asap. 
rformato: @karellm it is now ready for you to review, thanks
karellm: I believe you missed my other question. If I understand correctly, you want:

1. That empty tags stay: `<strong></strong>` stays `<strong></strong>`
2. That self-closing tags stay `<br />` stays `<br />`
3. What do you want to happen with `<br></br>`? And why would you even want to write that code in the first place?
rformato: oh, sorry @karellm, I'll try to explain:

1. correct
2. correct
3. I think the parser should leave that as the developer wrote it. I don't think the parser should "fix" developer errors, but transparently output the tags as they were written. I think it is up to the developer to read error messages triggered later on, at build time or at run time, and fix them. Ideally no developer will write wrong jsx on purpose, but in case it happens, that error will be transparently output to the language files, and more easily understood and fixed. I would prefer by far reading an error message telling the errors I am doing rather that having the parser silently fix them, denying me the opportunity to learn something new and get better.

I hope it makes sense for you. If that does not sound right for you, I'm more than happy to get your advise

Patch:
diff --git a/src/lexers/jsx-lexer.js b/src/lexers/jsx-lexer.js
index aef2ef9..bd16bf5 100644
--- a/src/lexers/jsx-lexer.js
+++ b/src/lexers/jsx-lexer.js
@@ -126,15 +126,15 @@ export default class JsxLexer extends JavascriptLexer {
             case 'text':
               return child.content
             case 'tag':
-              const elementName =
+              const useTagName =
                 child.isBasic &&
                 this.transSupportBasicHtmlNodes &&
                 this.transKeepBasicHtmlNodesFor.includes(child.name)
-                  ? child.name
-                  : index
-              return `<${elementName}>${elemsToString(
-                child.children
-              )}</${elementName}>`
+              const elementName = useTagName ? child.name : index
+              const childrenString = elemsToString(child.children)
+              return childrenString || !(useTagName && child.selfClosing)
+                ? `<${elementName}>${childrenString}</${elementName}>`
+                : `<${elementName} />`
             default:
               throw new Error('Unknown parsed content: ' + child.type)
           }
@@ -166,6 +166,7 @@ export default class JsxLexer extends JavascriptLexer {
             children: this.parseChildren(child.children, sourceText),
             name,
             isBasic,
+            selfClosing: child.kind === ts.SyntaxKind.JsxSelfClosingElement
           }
         } else if (child.kind === ts.SyntaxKind.JsxExpression) {
           // strip empty expressions


Test patch:
diff --git a/test/lexers/jsx-lexer.test.js b/test/lexers/jsx-lexer.test.js
index 75e4f6b..0deaa2d 100644
--- a/test/lexers/jsx-lexer.test.js
+++ b/test/lexers/jsx-lexer.test.js
@@ -317,6 +317,20 @@ describe('JsxLexer', () => {
         assert.equal(Lexer.extract(content)[0].defaultValue, 'Some Content')
         done()
       })
+
+      it('output self-closing when transSupportBasicHtmlNodes is true and element is self-closing', (done) => {
+        const Lexer = new JsxLexer({transSupportBasicHtmlNodes: true})
+        const content = '<Trans>a<br />b</Trans>'
+        assert.equal(Lexer.extract(content)[0].defaultValue, 'a<br />b')
+        done()
+      })
+
+      it('do not output self-closing when transSupportBasicHtmlNodes is true but element is not self-closing', (done) => {
+        const Lexer = new JsxLexer({transSupportBasicHtmlNodes: true})
+        const content = '<Trans>a<strong></strong>b</Trans>'
+        assert.equal(Lexer.extract(content)[0].defaultValue, 'a<strong></strong>b')
+        done()
+      })
     })
   })
 })