Question

I'm getting a multiline plain text from my backend.

For example:

Lorem ipsum dolor sit amet, <strong>consectetur</strong> adipiscing elit.

Nunc porta velit ut nunc pretium, quis auctor nunc placerat.
In quis porta neque.
Fusce dapibus faucibus mi ut egestas.

<p>Phasellus egestas magna posuere, bibendum dui quis, lacinia nisl.</p>

I want to render it with AngularJS as an HTML paragraphs.

So this example will become:

<p>Lorem ipsum dolor sit amet, &lt;strong&gt;consectetur&lt;/strong&gt; adipiscing elit.</p>

<p>Nunc porta velit ut nunc pretium, quis auctor nunc placerat.
In quis porta neque.
Fusce dapibus faucibus mi ut egestas.</p>

<p>&lt;p&gt;Phasellus egestas magna posuere, bibendum dui quis, lacinia nisl.&lt;/p&gt;</p>

Please notice, that all HTML code that existed in the initial plain text must be securely escaped (including existing <p>'s) so I can't just apply my filter and do escaping afterwards.

I see it as a 3 steps process:

  1. Escape HTML inclusions in initial text.
  2. Apply filter to break multiline text to paragraphs.
  3. Output text without further escaping.

But I'm not sure what is the best method of implementing each step.

Could you guide me with the right approach vector? Thank you!

Was it helpful?

Solution

I think I've finally solved this issue. I hope this answer will help someone.

As I mentioned earlier this is a 3-steps process.

  1. Escape HTML inclusions in initial text.
  2. Apply filter to break multiline text to paragraphs.
  3. Output text without further escaping.

For the first step I were trying to find some existing function to escape initial text, but to no avail. Seems like AngularJS is not exposing any methods of doing this (please correct me if I'm wrong). Finally I've created my own filter to escape HTML:

myModule.filter('htmlEscape', function() {
    return function(input) {
        if (!input) {
            return '';
        }
        return input.
            replace(/&/g, '&amp;').
            replace(/</g, '&lt;').
            replace(/>/g, '&gt;').
            replace(/'/g, '&#39;').
            replace(/"/g, '&quot;')
        ;
    };
});

Then I've created a filter to break plain text into paragraphs:

myModule.filter('textToHtml', ['$sce', 'htmlEscapeFilter', function($sce, htmlEscapeFilter) {
    return function(input) {
        if (!input) {
            return '';
        }
        input = htmlEscapeFilter(input);

        var output = '';
        $.each(input.split("\n\n"), function(key, paragraph) {
            output += '<p>' + paragraph + '</p>';
        });

        return $sce.trustAsHtml(output);
    };
}])

I'm injecting early created htmlEscape filter to it and using $sce.trustAsHtml method to return value suitable for use with ng-bind-html directive.

And in the end I'm invoking this filter in the partial template like this:

<div ng-bind-html="someText|textToHtml"></div>

Here's the result:

Result of applying the filter

OTHER TIPS

I would look at using the ng-sanitze module in the Angular API. I think that should cover what you are looking for.

$sanitize

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top