forked from stenciljs/output-targets
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreplace-tag-directive.ts
69 lines (59 loc) · 2.2 KB
/
replace-tag-directive.ts
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
import { AfterViewChecked, Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import { StencilProxyComponent } from './stencil-proxy-component';
@Directive({
selector: '[replaceTag]',
})
export class ReplaceTagDirective implements AfterViewChecked {
constructor(
private templateRef: TemplateRef<any>,
private vcf: ViewContainerRef,
private host: StencilProxyComponent
) {}
private _tag: string;
private _needUpdate: boolean = false;
private _webComponentElement: HTMLElement;
@Input('replaceTag')
set tag(t: string) {
this._tag = t;
this._needUpdate = true;
this.vcf.clear();
let template = this.templateRef.elementRef.nativeElement.previousElementSibling;
if (template) {
this.templateRef.elementRef.nativeElement.parentNode.removeChild(template);
}
this.vcf.createEmbeddedView(this.templateRef);
}
ngAfterViewChecked() {
if (this._needUpdate) {
this._updateTemplate();
this._needUpdate = false;
}
}
private _updateTemplate() {
let template = this.templateRef.elementRef.nativeElement.previousElementSibling;
if (template) {
this._webComponentElement = document.createElement(this._tag);
this.mirrorProperties(
this.templateRef.elementRef.nativeElement.previousElementSibling,
this._webComponentElement
);
Array.from(template.childNodes).forEach((node) => {
this._webComponentElement.appendChild(node as Node);
});
this.templateRef.elementRef.nativeElement.parentNode.replaceChild(this._webComponentElement, template);
// template.style.display = 'none';
// this.templateRef.elementRef.nativeElement.parentNode.appendChild(this._webComponentElement, template);
}
}
public handlePropertyChanges() {
this.mirrorProperties(this.templateRef.elementRef.nativeElement.parentElement, this._webComponentElement);
}
private mirrorProperties(from: HTMLElement, to: HTMLElement) {
const properties: [string, any][] = Object.entries(from);
for (let [key, value] of properties) {
if (this.host.availableInputProperties.includes(key) && value !== undefined) {
(to as Record<string, any>)[key] = value;
}
}
}
}