Skip to content

Commit de2182f

Browse files
committed
Remove event binding from code editors transformed to markdown cells
1 parent 11ace76 commit de2182f

File tree

3 files changed

+63
-12
lines changed

3 files changed

+63
-12
lines changed

packages/jupyterlab-lsp/src/adapters/adapter.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
9696
protected app: JupyterFrontEnd;
9797

9898
public activeEditorChanged: Signal<WidgetAdapter<T>, IEditorChangedData>;
99+
public editorRemoved: Signal<WidgetAdapter<T>, IEditorChangedData>;
99100
public update_finished: Promise<void>;
100101

101102
/**
@@ -117,6 +118,7 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
117118
this.connection_manager = extension.connection_manager;
118119
this.adapterConnected = new Signal(this);
119120
this.activeEditorChanged = new Signal(this);
121+
this.editorRemoved = new Signal(this);
120122
this.adapters = new Map();
121123
this.status_message = new StatusMessage();
122124
this.isConnected = false;

packages/jupyterlab-lsp/src/adapters/notebook/notebook.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,42 @@ export class NotebookAdapter extends WidgetAdapter<NotebookPanel> {
136136
);
137137

138138
this.widget.content.activeCellChanged.connect(this.activeCellChanged, this);
139+
this.widget.model.cells.changed.connect((cells, change) => {
140+
console.log(change);
141+
142+
if (change.type !== 'set') {
143+
return;
144+
}
145+
let convertedToMarkdown = [];
146+
147+
if (change.newValues.length !== change.oldValues.length) {
148+
// during conversion the cells should not get deleted nor added
149+
return;
150+
}
151+
152+
for (let i = 0; i < change.newValues.length; i++) {
153+
if (
154+
change.oldValues[i].type === 'code' &&
155+
change.newValues[i].type === 'markdown'
156+
) {
157+
convertedToMarkdown.push(change.newValues[i]);
158+
}
159+
}
160+
161+
for (let cellModel of convertedToMarkdown) {
162+
let cellWidget = this.widget.content.widgets.find(
163+
cell => cell.model.id === cellModel.id
164+
);
165+
166+
// for practical purposes this editor got removed from our consideration;
167+
// it might seem that we should instead look for the editor indicated by
168+
// the oldValues[i] cellModel, but this one got already transferred to the
169+
// markdown cell in newValues[i]
170+
this.editorRemoved.emit({
171+
editor: cellWidget.editor
172+
});
173+
}
174+
});
139175
}
140176

141177
get editors(): CodeEditor.IEditor[] {

packages/jupyterlab-lsp/src/virtual/codemirror_editor.ts

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,15 @@ export class CodeMirrorVirtualEditor
280280
};
281281
this._event_wrappers.set([eventName, handler], wrapped_handler);
282282

283-
this.forEveryBlockEditor(cm_editor => {
284-
cm_editor.on(eventName, wrapped_handler);
285-
});
283+
this.forEveryBlockEditor(
284+
cm_editor => {
285+
cm_editor.on(eventName, wrapped_handler);
286+
},
287+
true,
288+
cm_editor => {
289+
cm_editor.off(eventName, wrapped_handler);
290+
}
291+
);
286292
}
287293

288294
off(eventName: string, handler: CodeMirrorHandler, ...args: any[]): void {
@@ -496,20 +502,17 @@ export class CodeMirrorVirtualEditor
496502
return 0;
497503
}
498504

499-
addEventListener(type: string, listener: EventListenerOrEventListenerObject) {
500-
this.forEveryBlockEditor(cm_editor => {
501-
cm_editor.getWrapperElement().addEventListener(type, listener);
502-
});
503-
}
504-
505505
forEveryBlockEditor(
506506
callback: (cm_editor: CodeMirror.Editor) => any,
507-
monitor_for_new_blocks = true
507+
monitor_for_new_blocks = true,
508+
on_editor_removed_callback: (cm_editor: CodeMirror.Editor) => any = null
508509
) {
509510
const editors_with_handlers = new Set<CodeMirror.Editor>();
510511

511-
// TODO... the need of iterating over all editors is universal. How does the virtual
512-
// editor gets knowledge of the editor instances? From the adapter obviously.
512+
// TODO... the need of iterating over all editors is universal - so this could be
513+
// generalised to the VirtualEditor rather than live in CodeMirrorVirtualEditor;
514+
// How would the VirtualEditor get knowledge of the editor instances?
515+
// From the adapter (obviously).
513516
for (let editor of this.adapter.editors) {
514517
let cm_editor = (editor as CodeMirrorEditor).editor;
515518
editors_with_handlers.add(cm_editor);
@@ -528,6 +531,16 @@ export class CodeMirrorVirtualEditor
528531
}
529532
}
530533
);
534+
this.adapter.editorRemoved.connect(
535+
(adapter, data: IEditorChangedData) => {
536+
let { editor } = data;
537+
if (editor == null) {
538+
return;
539+
}
540+
let cm_editor = (editor as CodeMirrorEditor).editor;
541+
on_editor_removed_callback(cm_editor);
542+
}
543+
);
531544
}
532545
}
533546

0 commit comments

Comments
 (0)