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
- Output shown using
ng-bind-html
that hasn't gone through$sce.trustAsHtml
- Anything passed through
linky
, as can be seen in the linky source, it calls$sanitize
.
So, you can avoid HTML going through $sanitize
as long as
- You pass the string through $sce.trustAsHtml
- You don't pass it through the Angular provided linky filter, but roll your own that doesn't
$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