bublejs / buble

https://buble.surge.sh
MIT License
870 stars 67 forks source link

putting emoji's HTML entities emits square boxes instead of actual emoji #235

Open gaeulbyul opened 4 years ago

gaeulbyul commented 4 years ago

Input:

<div>&#x1F408;&#x1F415;&#128007;&#128017;</div>;

Expected:

React.createElement( 'div', null, "🐈🐕🐇🐑" );

Actual:

React.createElement( 'div', null, "" );
mourner commented 4 years ago

Not sure how this is related to Buble. Can you share a test case from https://buble.surge.sh/?

gaeulbyul commented 4 years ago

When I insert emoji in HTML entity like this, Buble decodes it to square box character instead of intended emoji.

For example, inserting <div>&#x1F408;&#x1F415;&#128007;&#128017;</div> transforms into React.createElement( 'div', null, "" ) but I think it would be React.createElement( 'div', null, "🐈🐕🐇🐑").

image

kzc commented 4 years ago

Report this bug to https://github.com/acornjs/acorn-jsx. It's emitting only the lower half of the UTF-16 surrogate pair.

As a workaround you can patch your local copy of acorn-jsx with:

--- a/node_modules/acorn-jsx/index.js
+++ b/node_modules/acorn-jsx/index.js
@@ -210,11 +210,11 @@
             if (str[1] === 'x') {
               str = str.substr(2);
               if (hexNumber.test(str))
-                entity = String.fromCharCode(parseInt(str, 16));
+                entity = String.fromCodePoint(parseInt(str, 16));
             } else {
               str = str.substr(1);
               if (decimalNumber.test(str))
-                entity = String.fromCharCode(parseInt(str, 10));
+                entity = String.fromCodePoint(parseInt(str, 10));
             }
           } else {
             entity = XHTMLEntities[str];

Bublé 0.20.0 without acorn-jsx patch:

$ echo '<div>&#65; &#x42; &#x1F415; &#128007; </div>;' | bin/buble
React.createElement( 'div', null, "A B   " );

Bublé 0.20.0 with acorn-jsx patch:

echo '<div>&#65; &#x42; &#x1F415; &#128007; </div>;' | bin/buble
React.createElement( 'div', null, "A B 🐕 🐇 " );