import { Document } from "../../Document" ; import { Helper , RTFJSError } from "../../Helper" ; import { GlobalState } from "../Containers" ; import { RtfDestination } from "./RtfDestination" ; export abstract class DestinationFactory < T extends IDestination > { public class : new ( parser , inst , name , param ) => T ; public newDestination ( parser , inst , name , param ) { return new this . class ( parser , inst , name , param ) ; } } export interface IDestination { _name : string ; setMetadata ? ( metaprop , metavalue ) : void ; apply ? ( ) : void ; appendText ? ( text ) : void ; sub ? ( ) : IDestination ; handleKeyword ? ( keyword , param ) : void | boolean ; handleBlob ? ( blob ) : void ; [ key ] : any ; } export const findParentDestination = ( parser , dest ) => { let state = parser . state ; while ( state != null ) { if ( state . destination == null ) { break ; } if ( state . destination . _name === dest ) { return state . destination ; } state = state . parent ; } Helper . log ( "findParentDestination() did not find destination " + dest ) ; } ; export class DestinationBase implements IDestination { public _name : string ; constructor ( name ) { this . _name = name ; } } export class DestinationTextBase implements IDestination { public _name : string ; public text : string ; constructor ( name ) { this . _name = name ; this . text = "" ; } public appendText ( text ) { this . text += text ; } } export abstract class DestinationFormattedTextBase implements IDestination { public _name : string ; protected parser : GlobalState ; private _records : ( ( rtf : RtfDestination ) => void ) [ ] ; constructor ( parser , name ) { this . parser = parser ; this . _name = name ; this . _records = [ ] ; } public appendText ( text ) { this . _records . push ( ( rtf ) => { rtf . appendText ( text ) ; } ) ; } public handleKeyword ( keyword , param ) { this . _records . push ( ( rtf ) => { return rtf . handleKeyword ( keyword , param ) ; } ) ; } public apply ( ) { const rtf = findParentDestination ( this . parser , "rtf" ) as any as RtfDestination ; if ( rtf == null ) { throw new RTFJSError ( "IDestination " + this . _name + " is not child of rtf destination" ) ; } const len = this . _records . length ; let doRender = true ; if ( this . renderBegin != null ) { doRender = this . renderBegin ( rtf , len ) ; } if ( doRender ) { for ( let i = 0 ; i < len ; i ++ ) { this . _records [ i ] ( rtf ) ; } if ( this . renderEnd != null ) { this . renderEnd ( rtf , len ) ; } } delete this . _records ; } public abstract renderBegin ( rtf , records ) ; public abstract renderEnd ( rtf , records ) ; } export interface IGenericPropertyDestination extends IDestination { apply ( ) : void ; } export class GenericPropertyDestinationFactory extends DestinationFactory < IGenericPropertyDestination > { constructor ( parentdest , metaprop ) { super ( ) ; this . class = class extends DestinationTextBase implements IGenericPropertyDestination { private parser : GlobalState ; constructor ( parser , inst , name ) { super ( name ) ; this . parser = parser ; } public apply ( ) { const dest = findParentDestination ( this . parser , parentdest ) ; if ( dest == null ) { throw new RTFJSError ( "IDestination " + this . _name + " must be within " + parentdest + " destination" ) ; } if ( dest . setMetadata == null ) { throw new RTFJSError ( "IDestination " + parentdest + " does not accept meta data" ) ; } dest . setMetadata ( metaprop , this . text ) ; } } ; } } export interface IGenericSubTextPropertyDestination extends IDestination { apply ( ) : void ; } export class GenericSubTextPropertyDestinationFactory extends DestinationFactory < IGenericSubTextPropertyDestination > { constructor ( name , parentDest , propOrFunc ) { super ( ) ; this . class = class extends DestinationTextBase implements IGenericSubTextPropertyDestination { private parser : GlobalState ; constructor ( parser ) { super ( name ) ; this . parser = parser ; } public apply ( ) { const dest = findParentDestination ( this . parser , parentDest ) ; if ( dest == null ) { throw new RTFJSError ( this . _name + " destination must be child of " + parentDest + " destination" ) ; } if ( dest [ propOrFunc ] == null ) { throw new RTFJSError ( this . _name + " destination cannot find member + " + propOrFunc + " in " + parentDest + " destination" ) ; } if ( dest [ propOrFunc ] instanceof Function ) { dest [ propOrFunc ] ( this . text ) ; } else { dest [ propOrFunc ] = this . text ; } } } ; } } export class RequiredDestinationFactory extends DestinationFactory < IDestination > { constructor ( name ) { super ( ) ; this . class = class extends DestinationBase implements IDestination { constructor ( ) { super ( name ) ; } } ; } }