Skip to content

Commit

Permalink
Add support for shouldUnescape in jsx-lexer - closes #678
Browse files Browse the repository at this point in the history
  • Loading branch information
karellm committed Nov 11, 2022
1 parent d739ce1 commit 0c0d371
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 13 deletions.
35 changes: 35 additions & 0 deletions src/helpers.js
Expand Up @@ -260,6 +260,40 @@ function makeDefaultSort(pluralSeparator) {
}
}

// unescape common html entities
// code from react-18next taken from
// https://github.com/i18next/react-i18next/blob/d3247b5c232f5d8c1a154fe5dd0090ca88c82dcf/src/unescape.js
function unescape(text) {
const matchHtmlEntity =
/&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g
const htmlEntities = {
'&': '&',
'&': '&',
'&lt;': '<',
'&#60;': '<',
'&gt;': '>',
'&#62;': '>',
'&apos;': "'",
'&#39;': "'",
'&quot;': '"',
'&#34;': '"',
'&nbsp;': ' ',
'&#160;': ' ',
'&copy;': '©',
'&#169;': '©',
'&reg;': '®',
'&#174;': '®',
'&hellip;': '…',
'&#8230;': '…',
'&#x2F;': '/',
'&#47;': '/',
}

const unescapeHtmlEntity = (m) => htmlEntities[m]

return text.replace(matchHtmlEntity, unescapeHtmlEntity)
}

export {
dotPathToHash,
mergeHashes,
Expand All @@ -268,4 +302,5 @@ export {
getSingularForm,
getPluralSuffixPosition,
makeDefaultSort,
unescape,
}
29 changes: 17 additions & 12 deletions src/lexers/jsx-lexer.js
@@ -1,5 +1,6 @@
import JavascriptLexer from './javascript-lexer.js'
import ts from 'typescript'
import { unescape } from '../helpers.js'

export default class JsxLexer extends JavascriptLexer {
constructor(options = {}) {
Expand Down Expand Up @@ -91,18 +92,6 @@ export default class JsxLexer extends JavascriptLexer {
const entry = {}
entry.key = getKey(tagNode)

const defaultsProp = getPropValue(tagNode, 'defaults')
const defaultValue =
defaultsProp || this.nodeToString.call(this, node, sourceText)

if (defaultValue !== '') {
entry.defaultValue = defaultValue

if (!entry.key) {
entry.key = entry.defaultValue
}
}

const namespace = getPropValue(tagNode, 'ns')
if (namespace) {
entry.namespace = namespace
Expand Down Expand Up @@ -143,6 +132,22 @@ export default class JsxLexer extends JavascriptLexer {
} else entry[property.name.text] = true
})

const defaultsProp = getPropValue(tagNode, 'defaults')
let defaultValue =
defaultsProp || this.nodeToString.call(this, node, sourceText)

if (entry.shouldUnescape === true) {
defaultValue = unescape(defaultValue)
}

if (defaultValue !== '') {
entry.defaultValue = defaultValue

if (!entry.key) {
entry.key = entry.defaultValue
}
}

return entry.key ? entry : null
} else if (tagNode.tagName.text === 'Interpolate') {
const entry = {}
Expand Down
12 changes: 11 additions & 1 deletion test/lexers/jsx-lexer.test.js
Expand Up @@ -314,7 +314,7 @@ describe('JsxLexer', () => {
done()
})

it('invalid interpolation gets stripped', (done) => {
it('strips invalid interpolation', (done) => {
const Lexer = new JsxLexer()
const content =
'<Trans count={count}>before{{ key1, key2 }}after</Trans>'
Expand Down Expand Up @@ -379,6 +379,16 @@ describe('JsxLexer', () => {
)
done()
})

it('supports the shouldUnescape options', (done) => {
const Lexer = new JsxLexer()
const content = '<Trans shouldUnescape>I&apros;m Cielquan</Trans>'
assert.equal(
Lexer.extract(content)[0].defaultValue,
'I&apros;m Cielquan'
)
done()
})
})
})
})

0 comments on commit 0c0d371

Please sign in to comment.