import * as Char from "../../web/static/js/char" ; import Editor from "../../web/static/js/editor" ; import { EditorSocket } from "../../web/static/js/editor_socket" ; export class TestChannel { private sockets : TestEditorSocket [ ] ; constructor ( ) { this . sockets = [ ] ; } public register ( socket ) { this . sockets . push ( socket ) ; } public send ( sender , message ) { this . sockets . forEach ( socket => { if ( socket !== sender ) { socket . receive ( message ) ; } } ) ; } } export class TestEditorSocket extends EditorSocket { private messageQueue : any [ ] ; private fakeChannel : TestChannel ; constructor ( documentId , channel ) { super ( documentId , ( ) => { } , ( ) => { } ) ; this . messageQueue = [ ] ; this . fakeChannel = channel ; this . fakeChannel . register ( this ) ; } public connect ( initCallback , changeCallback ) { this . initCallback = initCallback ; this . changeCallback = changeCallback ; } public sendChange ( change , lamport ) { this . fakeChannel . send ( this , { change , lamport } ) ; } public sendCursor ( cursor ) { } public receive ( message ) { this . messageQueue . push ( message ) ; } public letOneThrough ( ) { if ( this . messageQueue . length === 0 ) { throw Error ( "No messages left in queue!" ) ; } const message = this . messageQueue . shift ( ) ; this . changeCallback ( message ) ; } public letAllThrough ( ) { while ( this . messageQueue . length > 0 ) { this . letOneThrough ( ) ; } } public duplicateAllMessages ( ) { this . messageQueue = this . messageQueue . concat ( this . messageQueue ) ; } } export class TestEditor extends Editor { public getText ( ) { if ( this . codemirror . getValue ( ) !== this . crdt . toString ( ) ) { throw Error ( "Editor text and stored text do no match" ) ; } return this . codemirror . getValue ( ) ; } public type ( insertion ) { const doc = this . codemirror . getDoc ( ) ; doc . replaceRange ( insertion , doc . getCursor ( ) , doc . getCursor ( ) , "+input" ) ; } public delete ( count = 1 ) { for ( let i = 0 ; i < count ; i ++ ) { ( this . codemirror as any ) . execCommand ( "delCharAfter" ) ; } } public backspace ( count = 1 ) { for ( let i = 0 ; i < count ; i ++ ) { ( this . codemirror as any ) . execCommand ( "delCharBefore" ) ; } } public doUndo ( ) { this . undo ( ) ; } public doRedo ( ) { this . redo ( ) ; } public moveCursor ( update ) { const doc = this . codemirror . getDoc ( ) ; doc . setCursor ( update ( doc . getCursor ( ) ) ) ; } public moveCursorLeft ( amount = 1 ) { this . moveCursor ( ( { line , ch } ) => ( { line , ch : ch - amount } ) ) ; } public moveCursorRight ( amount = 1 ) { this . moveCursor ( ( { line , ch } ) => ( { line , ch : ch + amount } ) ) ; } public letOneThrough ( ) { ( this . editorSocket as TestEditorSocket ) . letOneThrough ( ) ; } public letAllThrough ( ) { ( this . editorSocket as TestEditorSocket ) . letAllThrough ( ) ; } public duplicateAllMessages ( ) { ( this . editorSocket as TestEditorSocket ) . duplicateAllMessages ( ) ; } public init ( val , site ) { this . onInit ( { site , state : val , } ) ; } } export function createEditors ( n ) { const editors = [ ] ; const channel = new TestChannel ( ) ; for ( let i = 0 ; i < n ; i ++ ) { const textarea = document . createElement ( "textarea" ) ; document . body . appendChild ( textarea ) ; const editor = new TestEditor ( textarea , new TestEditorSocket ( "mydoc" , channel ) , ( ) => { } ) ; editor . init ( [ ] , i ) ; editors . push ( editor ) ; } return editors ; }