8

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!

Slava Fomin II
  • 26,865
  • 29
  • 124
  • 202
  • 2
    Is SO a "send your requirements, and developers will develop solution for you" community ? – Jayesh Chandrapal Apr 08 '14 at 18:39
  • 1
    I'm downvoting this question because you haven't shown any research effort or included any code showing [what you've tried](http://whathaveyoutried.com). Why should I invest my time into doing your work for you when you're not even willing to invest your own time into solving the problem? – zzzzBov Apr 08 '14 at 18:44
  • 2
    This is a conceptual question. I'm not asking you to do the work for me. I'm asking for guidance of a more experience AngularJS developers as I'm just starting to learn it. Maybe I've overdetailed it, but I just wanted to be clear with my use case. I'm seeing a much worse questions with copy-pasted code on SO all the time. By the way, I've studied the documentation and some articles carefully and couldn't find proper approach vector to this problem as it is more complicated. – Slava Fomin II Apr 08 '14 at 18:57

2 Answers2

9

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

Slava Fomin II
  • 26,865
  • 29
  • 124
  • 202
  • Good effort but to honest thats what ng-sanitze is really for. Unless theres something specific I'm missing. – Asta Apr 08 '14 at 22:41
  • @Asta could you elaborate please? Is there a better way to solve depicted problem? – Slava Fomin II Apr 09 '14 at 08:42
  • @asta ng-sanitize would _remove_ text it doesn't like, not escape it. If there is a way to get it actually escaped with it I'd love to hear about it. – riffraff Jun 11 '14 at 13:25
-2

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

$sanitize

Asta
  • 1,569
  • 13
  • 23