AngularJS: How to bind-html-unsafe to an attribute? - angularjs

What is the correct way to make an unsafe bind to an attribute? In my case, I get undesired HTML entities in the title-attribute:
Link
(Angular 1.1.5)

" is how " is escaped in HTML (and XML) attributes, there's no way around it. It will display correctly on the page, however. Attribute contents aren't parsed as HTML so there's no need for an equivalent to bind-html-unsafe.

Related

How to render special characters like ™ in HTML with Angular JS

I have some special characters to show in various screens of my application so i wanted to have some way where i can handle special characters like "special char - æ ™ &amp" in controller/service instead of HTML.
I know i can use
ng-bind-html
to show special characters for the example string above. However i need to show same string in multiple screens so it would make more sense for me to do it in JS. Any alternative or equivalent JS side snippet for ng-bind-html?
Note: If you have come across these kind of strings you might be knowing that they can be rendered directly with HTML but if you are using Angular JS with
{{some scope value}}
then it doesn't format special characters on it's own.
You can use $sce like so:
function myCtrl($scope,$sce){
$scope.html = $sce.trustAsHtml('HTML_CODE;');
}
And then in your HTML you use ng-bind-html to bind the content to an element.
<span ng-bind-html="html"></span>

Angular render markup that is nested

I get JSON like this
{
"lots of":"keys"
"description" : {
"key":"Some sample key",
"value":"This is the markup™"
}
}
from server and I ultimately iterate the description objects and populate table rows with two columns: one for the key and one for the value.
I have tried putting on my <td> tag ng-bind-html as well as injecting $sce into my controller and using trustAsHtml but so far the string always displays as it is in the JSON. Not every value will be HTML but I can easily detect based on the key if HTML is a possibility. It seemed when I put in the directive on the td it did not display anything if no HTML was present. I am interested in using something that can allow HTML in the value but not require it so I can display either
HTML fragment
<tr ng-repeat="(key, val) in record.description">
<td>{{key}}:</td>
<td>{{val}}</td>
</tr>
I created a quick fiddle here:
https://jsfiddle.net/frishi/mvw97s3q/6/
I used angular-sanitize, which I am not sure you mentioned injecting in your module dependency list. Either way, the example works simply by using ng-bind-html
Relevant docs page: https://docs.angularjs.org/api/ng/directive/ngBindHtml
It works by using the directive ng-bind-html on the element you want to display the HTML string in. You use it like so:
<p ng-bind-html="data.firstName"></p>
assuming that data.firstName = "<strong>FeeFee</strong>" or something like that.
I would also like to add that Angular does not allow this natively because of legitimate security concerns. That and the fact that allowing arbitrary HTML to be rendered might not always produce desirable results. Your page layout could quite possibly break because of some HTML you allowed to be passed through.
Angular was designed with security in mind, and will prevent you from displaying HTML from raw strings whenever possible - to prevent various injection attacks.
Here is workarround for your problem: AngularJS: Insert HTML from a string. Generally you should use ng-bind-html insted of ng-bind (this is used by curly braces).

Can the `linky` filter be used with text containing html tags?

From the linky docs it seems it should work with ng-bind-html. However, if the text contains html tags, then linky overrides the actual html interpretation to transform URLs into links.
This can be seen by for instance writing
Pretty text with some links:<br/><img src="http://something.com/lol.gif">
http://angularjs.org/,
mailto:us#somewhere.org,
another#somewhere.org,
and one more: ftp://127.0.0.1/.
in the example at the bottom of the linky docs page.
Is there a way to firstly sanitise and interpret html using ng-bind-html and only later parse the resulting text to add clickable links?

How to change valid HTML tags that get rendered in ng-bind-html?

I have a text editor (textAngular) that I've modified to limit the number of valid HTML tags I can generate using that tool. Now, I want to only support a limited number of HTML elements (h3, h4, h5, h6, ol, ul) to produce a news story but I want to disable some of the valid HTML rendered by ng-bind-html. Namely, I want to remove , tags as a valid tags because they could have disastrous results for this user generated content.
Is it possible to remove and tags as something rendered by ng-bind-html?
Unfortunately no, it isn't possible to config the valid HTML tags.
The ng-bind-html use the $sanitize service to strip invalid tags/attributes, and you can see in the source code that all the configurations are private.
// Safe Block Elements - HTML5
var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
"aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
"h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
// Inline Elements - HTML5
var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," +
"bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
"samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
If you really want it, one way you could do is to copy the angular-sanitize.js and modify the valid HTML tags configuration directly.
Please note that if you do it that way, all the ng-bind-html in your entire application will be also affected. If that is undesired, you have to write your own custom directive and inject/use your modified version of $sanitize instead.
If you're into modifying textAngular already, you could modify something around the taCustomRenderers Section of the code and use ta-bind instead of ng-bind-html. They do nearly the same thing except ta-bind runs all the extra renderers.
Custom Renderers Code: textAngularSetup, textAngular - probably in this one you can do your stripping out of unwanted code.

Is it possible to use multiple lines in Angular attributes?

Is is possible to include a newline in an Angular JS expression in an attribute tag? Something like this:
<p ng-repeat="
foo in foos
| filter:{attr: 'something really long'}
| orderBy:bar">
{{foo}}
</p>
EDIT: To clarify, the above doesn't work. I was wondering if there is some other syntax that allows for breaking this kind of expressions into multiple lines.
angular.js parser would be able to handle it, but there's a quick regex check before handing it to the parser (see http://docs.angularjs.org/error/ngRepeat:iexp):
Be aware, the ngRepeat directive parses the expression using a regex
before sending collection and optionally id to the AngularJS parser.
This error comes from the regex parsing.
I filed a bug to loosen this restriction: https://github.com/angular/angular.js/issues/5537, you can hand-patch it in the meantime, it's just 1 character: m (/regex/m).
It is possible for an expressions to span multiple lines. But ng-repeat throws an error if you try to span the expression on multiple lines.
Take a look at this plunker:
Add a new line in the ng-repeat expression and open the browser console to see the error message.
http://plnkr.co/edit/E1O8Iy3VzL3kzj72BDUL?p=preview
Yes, it is possible to use multiline attributes with ANY HTML element, including AngularJS directives.

Resources