Skip to content

Commit

Permalink
feat: introduce htmlEncode pipe to encode HTML code to be rendered …
Browse files Browse the repository at this point in the history
…as string (#1575)

* add documentation note
  • Loading branch information
shauke committed Jan 16, 2024
1 parent b68ab76 commit c99e1d0
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
9 changes: 8 additions & 1 deletion docs/concepts/localization.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ In addition the dependency to Angular's internationalization tools (i18n) is nee

For more information refer to:

- [NGX-Translate: The internationalization (i18n) library for Angular](http://www.ngx-translate.com/)
- [NGX-Translate: The internationalization (i18n) library for Angular](https://github.com/ngx-translate/core)
- [Angular - Internationalization (i18n)](https://angular.io/guide/i18n)
- [ng-bootstrap Angular 9 support](https://github.com/ng-bootstrap/ng-bootstrap/issues/3537#issuecomment-586472803)

Expand Down Expand Up @@ -148,6 +148,13 @@ Usage in HTML:
<span [innerHTML]="'common.header.contact_no.text' | translate"></span>
```
> [!WARNING]
> Be aware to HTML encode possibly malicious HTML code since the `[innerHTML]` value will not automatically be sanitized.
> This is especially important if non validated user input is rendered directly.
> To HTML encode content we provide the `htmlEncode` pipe.
>
> example: `<p [innerHTML]="'search.noResult.message' | translate : { '0': searchTerm | htmlEncode }"></p>`
### Localization in the component(.ts) File
If you want to get the translation for a key within a component file, you have to:
Expand Down
2 changes: 2 additions & 0 deletions src/app/core/pipes.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { PricePipe } from './models/price/price.pipe';
import { DatePipe } from './pipes/date.pipe';
import { FeatureTogglePipe } from './pipes/feature-toggle.pipe';
import { HighlightPipe } from './pipes/highlight.pipe';
import { HtmlEncodePipe } from './pipes/html-encode.pipe';
import { MakeHrefPipe } from './pipes/make-href.pipe';
import { SanitizePipe } from './pipes/sanitize.pipe';
import { ServerSettingPipe } from './pipes/server-setting.pipe';
Expand All @@ -19,6 +20,7 @@ const pipes = [
DatePipe,
FeatureTogglePipe,
HighlightPipe,
HtmlEncodePipe,
MakeHrefPipe,
PricePipe,
ProductRoutePipe,
Expand Down
25 changes: 25 additions & 0 deletions src/app/core/pipes/html-encode.pipe.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { TestBed } from '@angular/core/testing';

import { HtmlEncodePipe } from './html-encode.pipe';

describe('Html Encode Pipe', () => {
let htmlEncodePipe: HtmlEncodePipe;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [HtmlEncodePipe],
});
htmlEncodePipe = TestBed.inject(HtmlEncodePipe);
});

it('should be created', () => {
expect(htmlEncodePipe).toBeTruthy();
});

it.each([
['<img src=https://test.jpg>', '&lt;img src=https://test.jpg&gt;'],
['?hello&world', '?hello&amp;world'],
])(`should transform '%s' to '%s'`, (input, output) => {
expect(htmlEncodePipe.transform(input)).toEqual(output);
});
});
13 changes: 13 additions & 0 deletions src/app/core/pipes/html-encode.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Pipe, PipeTransform } from '@angular/core';

/**
* The HTML encode pipe simply replaces HTML special characters like angle brackets (< and >) with HTML entities
* so they can be displayed as plain text in a web page.
* https://jasonwatmore.com/vanilla-js-html-encode-in-javascript
*/
@Pipe({ name: 'htmlEncode', pure: true })
export class HtmlEncodePipe implements PipeTransform {
transform(value: string): string {
return value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
}

0 comments on commit c99e1d0

Please sign in to comment.