I have a web app that uses messages from Twitter, for example.
A feed of JSON is used to build a list of messages, but characters such as 🙏👍👊 are displaying as question marks in a diamond. The element looks like this:
<div class="inner-message" ng-bind-html="unit.caption_text | linky:'_blank'"></div>
When I view the JSON url in Firefox and Chrome, these display fine.
Sample of head:
<!DOCTYPE html>
<html class="wf-opensans-n4-active wf-active" lang="en">
<head>
<meta charset="utf-8">
One thing I've found while debugging: when the messages are all in an array of objects, but not part of $scope, I can add them to the page and the emoji show correctly.
So I think something happens in Angular to do this. I've tried changing ng-bind-html to ng-bind, but that doesn't do it. I've tried removing ng-bind-html and using {{unit.caption_text}} inside the element, but it still breaks the unicode characters.
At the moment, I need to be able to use the linky filter, to display links correctly, so ng-bind-html is necessary, but I don't believe it's the problem.
Is something happening to them in javascript to break the encoding?
Is there a way to make them display correctly?
This shows icons as desired, but "linky" doesn't add formatting to links.
<div class="inner-message">{{unit.text}}</div>
This shows broken characters
<div class="inner-message" ng-bind-html="unit.text | linky:'_blank'"></div>
Got there in the end, making the changes as detailed in the Pull Request, which Michael linked, to stop the characters getting messed up.
I also found it helped give consistency if I added Symbola to the font stack for these messages. You can download Symbola from this page by George Douros . I ran it through a .ttf to .woff converter to get slightly better browser support, offering two alternatives.
No. Because emoji characters are treated as pictographs, they are encoded in Unicode based primarily on their general appearance, not on an intended semantic.
Emojis look like images, or icons, but they are not. They are letters (characters) from the UTF-8 (Unicode) character set.
The range of Unicode code points goes from U+0000 to U+10FFFF .
Note: This post does not display as intended on Chrome, as it doesn't support Emoji characters
It looks like Angular's $sanitize
service attempts to convert the characters to their HTML-entity equivalent. However, for certain single emoji characters, it splits it to 2. As can be seen at http://plnkr.co/edit/fDDen3bnnrQUvx3JfKgw?p=preview,
$scope.sanitizedText = $sanitize('🙈');
output in the template as
{{sanitizedText}}
shows ��
. Why? I don't know.
This means that anything using $sanitize
will effectively break such characters. This includes
ng-bind-html
that hasn't gone through $sce.trustAsHtml
linky
, as can be seen in the linky source, it calls $sanitize
.So, you can avoid HTML going through $sanitize
as long as
$sanitize
the input.An example filter is below:
app.filter('unsafeLinky', function($sce) {
// Regex from https://github.com/angular/angular.js/blob/master/src/ngSanitize/filter/linky.js#L5
var urlRegex = /(((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>])/gi;
return function(input, target) {
var targetHTML = target ? ' target="' + target + '"' : '';
return $sce.trustAsHtml(input.replace(urlRegex,'<a href="$1"' + targetHTML + '>$1</a>'));
}
});
Which can be used as
<p ng-bind-html="text | unsafeLinky:'_blank'"></p>
You can see a demo of this at http://plnkr.co/edit/sRJmt4YVO8udJInCd4Cy?p=preview
As suggested by the name, this unsafeLinky filter is unsafe. Be sure to trust where the original text comes from.
As suggested at the start of this answer, Chrome doesn't display Emoji characters properly. To get the characters showing in Chrome, you might have to use some sort of image-replacement. In any case, I suspect that is beyond the scope of this particular question.
Update
There is PR for Angular that might fix this, making the above work-around unnecessary once it's merged in: https://github.com/angular/angular.js/pull/6911
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With