Skip to content
Snippets Groups Projects
webpage-form-content.component.ts 2.42 KiB
Newer Older
import { AfterViewChecked, AfterViewInit, Component, ElementRef, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';

import { fromEvent, Subscription } from 'rxjs';

import { PrismService } from '../services/prism.service';

@Component({
    selector: 'app-webpage-form-content',
    templateUrl: 'webpage-form-content.component.html',
    styleUrls: ['webpage-form-content.component.scss']
})
export class WebpageFormContentComponent implements OnInit, AfterViewChecked, AfterViewInit, OnDestroy {
    @Input() form: UntypedFormGroup;
    @Input() controlName: string;
    @Input() controlLabel: string;

    @ViewChild('textArea', { static: true })
    textArea!: ElementRef;
    @ViewChild('codeContent', { static: true })
    codeContent!: ElementRef;
    @ViewChild('pre', { static: true })
    pre!: ElementRef;

    sub!: Subscription;
    highlighted = false;
    codeType = 'html';

    constructor(
        private prismService: PrismService,
        private renderer: Renderer2
    ) {}

    ngOnInit(): void {
        this.listenForm()
        this.synchronizeScroll();
        if (this.form.value[this.controlName]) {
            this.highlight(this.form.value[this.controlName]);
        }
    }

    ngAfterViewInit() {
        this.prismService.highlightAll();
    }

    ngAfterViewChecked() {
        if (this.highlighted) {
            this.prismService.highlightAll();
            this.highlighted = false;
        }
    }

    highlight(content: string) {
        const modifiedContent = this.prismService.convertHtmlIntoString(content);

        this.renderer.setProperty(this.codeContent.nativeElement, 'innerHTML', modifiedContent);

        this.highlighted = true;
    }

    ngOnDestroy() {
        this.sub?.unsubscribe();
    }

    private listenForm() {
        this.sub = this.form.valueChanges.subscribe(val => {
            this.highlight(val[this.controlName]);
        });
    }

    private synchronizeScroll() {
        const localSub  = fromEvent(this.textArea.nativeElement, 'scroll').subscribe(() => {
            const toTop = this.textArea.nativeElement.scrollTop;
            const toLeft = this.textArea.nativeElement.scrollLeft;

            this.renderer.setProperty(this.pre.nativeElement, 'scrollTop', toTop);
            this.renderer.setProperty(this.pre.nativeElement, 'scrollLeft', toLeft + 0.2);
        });

        this.sub.add(localSub);
    }
}