-
Notifications
You must be signed in to change notification settings - Fork 566
Expand file tree
/
Copy pathmetadata.directive.ts
More file actions
84 lines (77 loc) · 2.92 KB
/
Copy pathmetadata.directive.ts
File metadata and controls
84 lines (77 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import {
Directive,
ElementRef,
inject,
Input,
Renderer2,
SecurityContext,
} from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { MetadataValue } from '../core/shared/metadata.models';
import { normalizeLanguageCode } from './utils/normalize-language-code-utils';
/**
* A directive that sets the innerHTML and lang attribute of the host element
* based on the provided `MetadataValue`.
*
* - The `innerHTML` is set to the `value` property of the `MetadataValue`.
* - The `lang` attribute is set to the `language` property of the `MetadataValue`.
* - If the `MetadataValue` is null or undefined, the `innerHTML` is cleared and the `lang` attribute is removed.
*/
@Directive({
selector: '[dsMetadata]',
standalone: true,
})
export class MetadataDirective {
/**
* Stores the current `MetadataValue` provided to the directive.
*/
private _metadataValue?: MetadataValue;
/**
* Reference to the host DOM element.
*/
private el = inject(ElementRef);
/**
* Angular Renderer2 instance for safely manipulating the DOM.
*/
private renderer = inject(Renderer2);
/**
* Angular DomSanitizer instance used to sanitize the metadata value before
* inserting it into the DOM as innerHTML, preventing XSS attacks.
*/
private sanitizer = inject(DomSanitizer);
/**
* Input property for the directive. Accepts a `MetadataValue` object.
* When set, it updates the host element's `innerHTML` and `lang` attribute.
*
* @param value - The `MetadataValue` object containing the `value` and `language`.
*/
@Input() set dsMetadata(value: MetadataValue | null | undefined) {
this._metadataValue = value ?? undefined;
this.updateHost();
}
/**
* Updates the host element's `innerHTML` and `lang` attribute based on the current `MetadataValue`.
* - If `MetadataValue` is provided:
* - Sets `innerHTML` to the sanitized `MetadataValue.value` (or an empty string if `value` is null/undefined).
* - Sets the `lang` attribute to `MetadataValue.language` (or removes it if `language` is null/undefined).
* - If `MetadataValue` is null/undefined:
* - Clears the `innerHTML`.
* - Removes the `lang` attribute.
*/
private updateHost(): void {
if (this._metadataValue) {
const val = this._metadataValue.value ?? '';
const sanitizedVal = this.sanitizer.sanitize(SecurityContext.HTML, val) ?? '';
this.renderer.setProperty(this.el.nativeElement, 'innerHTML', sanitizedVal);
if (this._metadataValue.language) {
const normalizedLang = normalizeLanguageCode(this._metadataValue.language);
this.renderer.setAttribute(this.el.nativeElement, 'lang', normalizedLang);
} else {
this.renderer.removeAttribute(this.el.nativeElement, 'lang');
}
} else {
this.renderer.setProperty(this.el.nativeElement, 'innerHTML', '');
this.renderer.removeAttribute(this.el.nativeElement, 'lang');
}
}
}