@@ -11,6 +11,9 @@ import {
1111import { until_ready } from '../utils' ;
1212import { Signal } from '@phosphor/signaling' ;
1313
14+ type CodeMirrorHandler = ( instance : any , ...args : any [ ] ) => void ;
15+ type WrappedHandler = ( instance : CodeMirror . Editor , ...args : any [ ] ) => void ;
16+
1417/**
1518 * VirtualEditor extends the CodeMirror.Editor interface; its subclasses may either
1619 * fast-forward any requests to an existing instance of the CodeMirror.Editor
@@ -158,6 +161,44 @@ export abstract class VirtualEditor implements CodeMirror.Editor {
158161 ) : IEditorPosition {
159162 return this . virtual_document . root . transform_source_to_editor ( root_position ) ;
160163 }
164+
165+ abstract forEveryBlockEditor (
166+ callback : ( cm_editor : CodeMirror . Editor ) => void
167+ ) : void ;
168+
169+ private _event_wrappers = new Map < CodeMirrorHandler , WrappedHandler > ( ) ;
170+
171+ /**
172+ * Proxy the event handler binding to the CodeMirror editors,
173+ * allowing for multiple actual editors per a virtual editor.
174+ *
175+ * Only handlers accepting CodeMirror.Editor are supported for simplicity.
176+ */
177+ on ( eventName : string , handler : CodeMirrorHandler , ...args : any [ ] ) : void {
178+ let wrapped_handler = ( instance : CodeMirror . Editor , ...args : any [ ] ) => {
179+ try {
180+ return handler ( this , ...args ) ;
181+ } catch ( error ) {
182+ console . warn (
183+ 'Wrapped handler (which should accept a CodeMirror Editor instance) failed' ,
184+ { error, instance, args, this : this }
185+ ) ;
186+ }
187+ } ;
188+ this . _event_wrappers . set ( handler , wrapped_handler ) ;
189+
190+ this . forEveryBlockEditor ( cm_editor => {
191+ cm_editor . on ( eventName , wrapped_handler ) ;
192+ } ) ;
193+ }
194+
195+ off ( eventName : string , handler : CodeMirrorHandler , ...args : any [ ] ) : void {
196+ let wrapped_handler = this . _event_wrappers . get ( handler ) ;
197+
198+ this . forEveryBlockEditor ( cm_editor => {
199+ cm_editor . off ( eventName , wrapped_handler ) ;
200+ } ) ;
201+ }
161202}
162203
163204// tslint:disable-next-line:interface-name
0 commit comments