import { IPossiblyUntitledFile , IUntitledFile } from "@common/files" ; import { MainIpcHandlers } from "@main/MainIPC" ; import { to } from "@common/util/to" ; export abstract class Editor < TDocumentModel = any > { protected _editorElt : HTMLElement ; protected _mainProxy : MainIpcHandlers ; protected _currentFile : IPossiblyUntitledFile | null ; protected _unsavedChanges : boolean ; constructor ( file , editorElt , mainProxy ) { this . _currentFile = file || new IUntitledFile ( ) ; this . _unsavedChanges = false ; this . _editorElt = editorElt ; this . _mainProxy = mainProxy ; } private _createEmptyFile ( ) { return new IUntitledFile ( ) ; } /**
     * Called upon initialization.
     * Add event listeners, etc..
     */ abstract init ( ) ; /**
     * Called when the editor is being torn down.
     * Close files, remove event listeners, etc.
     */ abstract destroy ( ) ; /**
     * Convert the current contents of this editor to a string.
     */ abstract serializeContents ( ) ; param contents abstract parseContents ( contents ) ; param content abstract setContents ( content ) ; setCurrentFile ( file ) { console . log ( "editor :: setCurrentFile" , file ) ; this . _currentFile = file ; this . setContents ( this . parseContents ( file . contents ) ) ; this . handleDocChanged ( ) ; } setCurrentFilePath ( filePath ) { if ( ! this . _currentFile ) { this . _currentFile = this . _createEmptyFile ( ) ; } this . _currentFile . path = filePath ; this . handleDocChanged ( ) ; } async saveCurrentFile ( saveas = true ) { if ( ! this . _currentFile ) { console . error ( "editor :: saveCurrentFile :: no current file, cannot save!" ) ; return ; } this . _currentFile . contents = this . serializeContents ( ) ; console . log ( "saveCurrentFile ::" , this . _currentFile ) ; if ( saveas || this . _currentFile . path == null ) { let [ err ] = await to ( this . _mainProxy . dialog . dialogFileSaveAs ( this . _currentFile ) ) ; if ( err ) { return Promise . reject ( err ) ; } } else { let sendData = { contents : this . _currentFile . contents , creationTime : this . _currentFile . creationTime , dirPath : this . _currentFile . dirPath , modTime : this . _currentFile . modTime , name : this . _currentFile . name , parent : this . _currentFile . parent , path : this . _currentFile . path , type : this . _currentFile . type , ext : this . _currentFile . ext , hash : this . _currentFile . hash } ; let [ err ] = await to ( this . _mainProxy . file . requestFileSave ( sendData ) ) ; if ( err ) { return Promise . reject ( err ) ; } } todo this . handleFileDidSave ( ) ; } async closeAndDestroy ( ) { console . log ( "editor :: closeAndDestroy" ) ; if ( this . _currentFile && this . _unsavedChanges ) { let [ err , choice ] = await to ( this . _mainProxy . dialog . askSaveDiscardChanges ( this . _currentFile . path || "<untitled>" ) ) ; if ( err ) { return Promise . reject ( err ) ; } if ( choice == "Cancel" ) { return Promise . reject ( choice ) ; } else if ( choice == "Save" || choice == "Save As" ) { let [ err ] = await to ( this . saveCurrentFile ( choice == "Save As" ) ) ; if ( err ) { return Promise . reject ( err ) ; } } else if ( choice == "Discard Changes" ) { } } this . destroy ( ) ; } handleDocChanged ( ) { this . _unsavedChanges = true ; } handleFileDidSave ( ) { this . _unsavedChanges = false ; } } export class DefaultEditor extends Editor < string > { _inputElt : HTMLTextAreaElement | null ; _initialized : boolean ; constructor ( file , editorElt , mainProxy ) { super ( file , editorElt , mainProxy ) ; this . _inputElt = null ; this . _initialized = false ; } init ( ) { if ( this . _initialized ) { return ; } this . _inputElt = document . createElement ( "textarea" ) ; this . _inputElt . value = this . _currentFile ?. contents || "" ; this . _editorElt . appendChild ( this . _inputElt ) ; this . _initialized = true ; } destroy ( ) { if ( this . _inputElt ) { this . _inputElt . remove ( ) ; } this . _inputElt = null ; this . _initialized = false ; } serializeContents ( ) { if ( ! this . _inputElt ) { return "" ; } return this . _inputElt . value ; } parseContents ( contents ) { return contents ; } setContents ( contents ) { if ( ! this . _inputElt ) { console . error ( "DefaultEditor :: setContents :: editor uninitialized!" ) ; return ; } this . _inputElt . value = contents ; } }