import { ElementRef , Injectable } from '@angular/core' ; import { WindowRef } from '../../../types/window-ref' ; import { CalendarOptions } from './calendar-options.model' ; @ Injectable ( ) export class CalendarHelper { private embeddedView : Window ; private embeddedViewReady = false ; constructor ( private windowRef ) { } public init ( calendarContainer , options , onDaySelected , onChangeMonth ) { if ( this . hasEmbeddedView ( calendarContainer ) ) { const iframe = < HTMLIFrameElement > calendarContainer . nativeElement ; iframe . onload = ( ) => { this . embeddedViewReady = true ; this . emitOptionsToEmbeddedView ( options ) ; } ; this . embeddedView = iframe . contentWindow ; this . windowRef . nativeWindow . addEventListener ( 'message' , ( event ) => this . handleMessageEvent ( event , onDaySelected , onChangeMonth ) ) ; } } public update ( options ) { if ( this . embeddedViewReady ) { this . emitOptionsToEmbeddedView ( options ) ; } } public setSelectedDay ( day ) { if ( this . embeddedViewReady ) { this . embeddedView . postMessage ( { type : 'kirbyCalendarSetSelectedDay' , selectedDay : day , } , '*' ) ; } } private hasEmbeddedView ( calendarContainer ) { return ( calendarContainer && calendarContainer . nativeElement && calendarContainer . nativeElement instanceof HTMLIFrameElement && calendarContainer . nativeElement . contentWindow ) ; } private emitOptionsToEmbeddedView ( options ) { this . embeddedView . postMessage ( { type : 'kirbyCalendarInit' , ... options , } , '*' ) ; } private handleMessageEvent ( event , onDaySelected , onChangeMonth ) { if ( this . validateMessage ( event ) ) { switch ( event . data . type ) { case 'kirbyCalendarDaySelected' : if ( this . validateDateSelectedMessage ( event ) ) { onDaySelected ( { isSelectable : true , date : event . data . day } ) ; } break ; case 'kirbyCalendarChangeMonth' : if ( this . validateNavigateMonthMessage ( event ) ) { onChangeMonth ( event . data . index ) ; } break ; } } } private validateMessage ( event ) { return ( this . embeddedView === event . source && event . type === 'message' && event . data && event . data . type ) ; } private validateDateSelectedMessage ( event ) { return event . data . type === 'kirbyCalendarDaySelected' && event . data . day ; } private validateNavigateMonthMessage ( event ) { return event . data . type === 'kirbyCalendarChangeMonth' && typeof event . data . index === 'number' ; } }