@@ -140,7 +140,8 @@ namespace ts {
140140 return createLiteral ( true ) ;
141141 }
142142 else if ( node . kind === SyntaxKind . StringLiteral ) {
143- return node ;
143+ const decoded = tryDecodeEntities ( ( < StringLiteral > node ) . text ) ;
144+ return decoded ? createLiteral ( decoded , /*location*/ node ) : node ;
144145 }
145146 else if ( node . kind === SyntaxKind . JsxExpression ) {
146147 return visitJsxExpression ( < JsxExpression > node ) ;
@@ -210,19 +211,31 @@ namespace ts {
210211 }
211212
212213 /**
213- * Decodes JSX entities.
214+ * Replace entities like " ", "{", and "�" with the characters they encode.
215+ * See https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
214216 */
215- function decodeEntities ( text : string ) {
216- return text . replace ( / & ( \w + ) ; / g, function ( s : any , m : string ) {
217- if ( entities [ m ] !== undefined ) {
218- return String . fromCharCode ( entities [ m ] ) ;
217+ function decodeEntities ( text : string ) : string {
218+ return text . replace ( / & ( ( # ( ( \d + ) | x ( [ \d a - f A - F ] + ) ) ) | ( \w + ) ) ; / g, ( match , _all , _number , _digits , decimal , hex , word ) => {
219+ if ( decimal ) {
220+ return String . fromCharCode ( parseInt ( decimal , 10 ) ) ;
221+ }
222+ else if ( hex ) {
223+ return String . fromCharCode ( parseInt ( hex , 16 ) ) ;
219224 }
220225 else {
221- return s ;
226+ const ch = entities [ word ] ;
227+ // If this is not a valid entity, then just use `match` (replace it with itself, i.e. don't replace)
228+ return ch ? String . fromCharCode ( ch ) : match ;
222229 }
223230 } ) ;
224231 }
225232
233+ /** Like `decodeEntities` but returns `undefined` if there were no entities to decode. */
234+ function tryDecodeEntities ( text : string ) : string | undefined {
235+ const decoded = decodeEntities ( text ) ;
236+ return decoded === text ? undefined : decoded ;
237+ }
238+
226239 function getTagName ( node : JsxElement | JsxOpeningLikeElement ) : Expression {
227240 if ( node . kind === SyntaxKind . JsxElement ) {
228241 return getTagName ( ( < JsxElement > node ) . openingElement ) ;
0 commit comments