Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS filter returning html as string

I've created an AngularJS filter to automatically create clickable links from addresses found in data. The filter:

app.filter('parseUrl', function() {
    var  //URLs starting with http://, https://, or ftp://
        replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim,
        //URLs starting with "www." (without // before it, or it'd re-link the ones done above).
        replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim,
        //Change email addresses to mailto:: links.
        replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;

        return function(text, target, otherProp) {        
            angular.forEach(text.match(replacePattern1), function(url) {
                text = text.replace(replacePattern1, "<a href=\"$1\" target=\"_blank\">$1</a>");
            });
            angular.forEach(text.match(replacePattern2), function(url) {
                text = text.replace(replacePattern2, "$1<a href=\"http://$2\" target=\"_blank\">$2</a>");
            });
            angular.forEach(text.match(replacePattern3), function(url) {
                text = text.replace(replacePattern3, "<a href=\"mailto:$1\">$1</a>");
            });

            return text;        
        };
    });

And here is how I'm calling it (inside a paragraph):

<p><strong>Details:</strong> {{event.description | parseUrl}}</p>

And this works correctly to replace the plain text links with the code for a link. However, it replaces it with the link literally as plain text. For example, www.google.com would get replaced with &lt;a href="http://www.google.com" target="_blank"&gt;http://google.com&lt;/a&gt;. This clearly doesn't make a clickable link, which was my goal.

I'm not sure why this is happening. Any ideas on how to prevent/fix it? Thanks.

like image 573
Jakemmarsh Avatar asked Jul 10 '13 01:07

Jakemmarsh


2 Answers

Try using the ngBindHtmlUnsafe directive to have the HTML that your filter produces applied as actual innerHTML contents of an element, like so:

<span ng-bind-html-unsafe="event.description | parseUrl"></span>
like image 150
Jollymorphic Avatar answered Sep 20 '22 02:09

Jollymorphic


You need to use either:

  • ngBindHtmlUnsafe
    If you 100% trust the source of the content
  • ngBindHtml
    If you don't trust the source of the content

Outputting a string using an expression will escape any html entities that you pass to it (symbols such as < > &)

like image 33
Clark Pan Avatar answered Sep 24 '22 02:09

Clark Pan