Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
GianlucaGuarini committed Dec 14, 2019
1 parent 9ec9ce8 commit 0a96fd7
Show file tree
Hide file tree
Showing 7 changed files with 353 additions and 19 deletions.
26 changes: 13 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -33,7 +33,7 @@
],
"devDependencies": {
"@babel/core": "^7.7.5",
"@babel/preset-env": "^7.7.5",
"@babel/preset-env": "^7.7.6",
"@riotjs/dom-bindings": "^4.5.0",
"chai": "^4.2.0",
"coveralls": "^3.0.9",
Expand All @@ -44,7 +44,7 @@
"node-sass": "^4.13.0",
"nyc": "^14.1.1",
"pug": "^2.0.4",
"rollup": "^1.27.8",
"rollup": "^1.27.13",
"rollup-plugin-alias": "^2.2.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-json": "^4.0.0",
Expand Down
11 changes: 9 additions & 2 deletions src/generators/template/expressions/text.js
Expand Up @@ -8,6 +8,7 @@ import {
import {createArrayString, transformExpression, wrapASTInFunctionWithScope} from '../utils'
import {nullNode,simplePropertyNode} from '../../../utils/custom-ast-nodes'
import {builders} from '../../../utils/build-types'
import encodeHTMLEntities from '../../../utils/html-entities/encode'
import {isLiteral} from '../../../utils/ast-nodes-checks'
import unescapeChar from '../../../utils/unescape-char'

Expand All @@ -20,14 +21,20 @@ import unescapeChar from '../../../utils/unescape-char'
function generateLiteralStringChunksFromNode(node, sourceCode) {
return node.expressions.reduce((chunks, expression, index) => {
const start = index ? node.expressions[index - 1].end : node.start
const string = sourceCode.substring(start, expression.start)
const string = encodeHTMLEntities(
sourceCode.substring(start, expression.start)
)

// trimStart the first string
chunks.push(index === 0 ? string.trimStart() : string)

// add the tail to the string
if (index === node.expressions.length - 1)
chunks.push(sourceCode.substring(expression.end, node.end).trimEnd())
chunks.push(
encodeHTMLEntities(
sourceCode.substring(expression.end, node.end).trimEnd()
)
)

return chunks
}, [])
Expand Down
5 changes: 4 additions & 1 deletion src/generators/template/utils.js
Expand Up @@ -21,6 +21,7 @@ import { nullNode, simplePropertyNode } from '../../utils/custom-ast-nodes'
import addLinesOffset from '../../utils/add-lines-offset'
import compose from 'cumpa'
import {createExpression} from './expressions/index'
import encodeHTMLEntities from '../../utils/html-entities/encode'
import generateAST from '../../utils/generate-ast'
import unescapeChar from '../../utils/unescape-char'

Expand Down Expand Up @@ -470,7 +471,9 @@ export function mergeAttributeExpressions(node, sourceFile, sourceCode) {

return [
...acc,
expression ? transformExpression(expression, sourceFile, sourceCode) : builders.literal(str)
expression ?
transformExpression(expression, sourceFile, sourceCode) :
builders.literal(encodeHTMLEntities(str))
]
}, [])
].filter(expr => !isLiteral(expr) || expr.value)
Expand Down
50 changes: 50 additions & 0 deletions src/utils/html-entities/encode.js
@@ -0,0 +1,50 @@
import entities from './entities.json'

const HTMLEntityRe = /&(\S+);/g
const HEX_NUMBER = /^[\da-fA-F]+$/
const DECIMAL_NUMBER = /^\d+$/

/**
* Encode unicode hex html entities like for example Ȣ
* @param {string} string - input string
* @returns {string} encoded string
*/
export function encodeHex(string) {
const hex = string.substr(2)

return HEX_NUMBER.test(hex) ?
String.fromCodePoint(parseInt(hex, 16)) :
string
}

/**
* Encode unicode decimal html entities like for example Þ
* @param {string} string - input string
* @returns {string} encoded string
*/
export function encodeDecimal(string) {
const nr = string.substr(1)

return DECIMAL_NUMBER.test(nr) ?
String.fromCodePoint(parseInt(nr, 10))
: string
}

/**
* Encode html entities in strings like  
* @param {string} string - input string
* @returns {string} encoded string
*/
export default function encodeHTMLEntities(string) {
return string.replace(HTMLEntityRe, (match, entity) => {
const [firstChar, secondChar] = entity

if (firstChar === '#') {
return secondChar === 'x' ?
encodeHex(entity) :
encodeDecimal(entity)
} else {
return entities[entity] || entity
}
})
}

0 comments on commit 0a96fd7

Please sign in to comment.