All files / app/features/editor iframe.service.ts

89.65% Statements 26/29
85.71% Branches 18/21
100% Functions 5/5
88.88% Lines 24/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 592x 2x   2x   2x                 2x 9x 9x 9x 9x 9x   9x 9x 9x     9x       10x       1x       3x 1x   2x 1x     1x   1x 1x 1x                  
import { inject, Injectable, OnDestroy } from '@angular/core';
import { WINDOW } from '@drevo-web/core';
import { InsertTagCommand } from '@drevo-web/shared';
import { BehaviorSubject, Observable, ReplaySubject, Subject } from 'rxjs';
 
const allowedOrigins = [
    'http://drevo-local.ru',
    'https://drevo-info.ru',
    'https://staging.drevo-info.ru',
    'https://app.drevo-info.ru',
    'http://localhost',
];
 
@Injectable()
export class IframeService implements OnDestroy {
    private readonly messageHandler = (event: MessageEvent): void => this.onMessage(event);
    private readonly window = inject(WINDOW);
    private readonly contentSubject = new ReplaySubject<string>(1);
    private readonly csrfTokenSubject = new BehaviorSubject<string | undefined>(undefined);
    private readonly insertTagSubject = new Subject<InsertTagCommand>();
 
    public readonly content$: Observable<string> = this.contentSubject.asObservable();
    public readonly csrfToken$: Observable<string | undefined> = this.csrfTokenSubject.asObservable();
    public readonly insertTag$ = this.insertTagSubject.asObservable();
 
    constructor() {
        this.window?.addEventListener('message', this.messageHandler);
    }
 
    ngOnDestroy(): void {
        this.window?.removeEventListener('message', this.messageHandler);
    }
 
    sendMessage(message: unknown): void {
        this.window?.parent.postMessage(message, '*');
    }
 
    private onMessage(event: MessageEvent): void {
        if (!allowedOrigins.includes(event.origin)) {
            return;
        }
        if (!event.data || typeof event.data.action === 'undefined') {
            return;
        }
 
        switch (event.data.action) {
            case 'loadContent':
                this.contentSubject.next(event.data.content);
                this.csrfTokenSubject.next(event.data.csrf);
                break;
            case 'insertTag':
                this.insertTagSubject.next(event.data.content);
                break;
            default:
                break;
        }
    }
}