Skip to content

Commit ae19779

Browse files
committed
Reintegrate the cellPrompt in create assignment cell widget
1 parent 4dcd41a commit ae19779

File tree

1 file changed

+65
-45
lines changed

1 file changed

+65
-45
lines changed

src/create_assignment/create_assignment_extension.ts

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,51 +3,41 @@ import {
33
Dialog,
44
Styling
55
} from '@jupyterlab/apputils';
6-
76
import {
87
Cell,
98
ICellModel
109
} from '@jupyterlab/cells';
11-
12-
// import {
13-
// IChangedArgs
14-
// } from '@jupyterlab/coreutils';
15-
10+
import { IChangedArgs } from '@jupyterlab/coreutils';
1611
import {
1712
DocumentRegistry
1813
} from '@jupyterlab/docregistry';
19-
2014
import {
2115
INotebookModel,
2216
INotebookTracker,
2317
Notebook,
2418
NotebookPanel
2519
} from '@jupyterlab/notebook';
2620
import { CellList } from '@jupyterlab/notebook/lib/celllist';
27-
2821
import {
2922
IObservableJSON,
3023
IObservableList,
3124
IObservableMap,
3225
} from '@jupyterlab/observables';
33-
3426
import {
3527
ReadonlyPartialJSONValue
3628
} from '@lumino/coreutils';
37-
3829
import {
3930
Message
4031
} from '@lumino/messaging';
41-
4232
import {
4333
ISignal,
4434
Signal
4535
} from '@lumino/signaling';
46-
4736
import {
4837
Panel,
4938
Widget
5039
} from '@lumino/widgets';
40+
5141
import {
5242
CellModel,
5343
CellType,
@@ -236,8 +226,9 @@ export class CreateAssignmentWidget extends Panel {
236226
*/
237227
class CellWidget extends Panel {
238228

239-
constructor(cellModel: ICellModel) {
229+
constructor(cellModel: ICellModel, notebookPanel?: NotebookPanel) {
240230
super();
231+
this._notebookPanel = notebookPanel;
241232
this._cellModel = cellModel;
242233
this._cellModel.metadata.changed.connect(
243234
this._onMetadataChange, this
@@ -247,6 +238,10 @@ class CellWidget extends Panel {
247238
this._initMetadata(cellModel);
248239
this.addClass(CSS_CELL_WIDGET);
249240
this.node.addEventListener('click', this._onClick.bind(this));
241+
this.cellModel.stateChanged.connect(this._onStateChange, this);
242+
243+
// Try to update the prompt (works only if cell widget has been created).
244+
this._updatePrompt();
250245
}
251246

252247
/**
@@ -275,6 +270,8 @@ class CellWidget extends Panel {
275270
this._onMetadataChange, this
276271
);
277272
this.node.removeEventListener('click', this._onClick);
273+
this.cellModel.stateChanged.disconnect(this._onStateChange, this);
274+
278275
if (this._taskInput != null) {
279276
this._taskInput.onchange = null;
280277
}
@@ -298,24 +295,46 @@ class CellWidget extends Panel {
298295
/**
299296
* Sets this cell as active/focused.
300297
*/
301-
setActive(active: boolean): void {
298+
setActive(active: boolean): void {
302299
if (active) {
303300
this.addClass(CSS_MOD_ACTIVE);
304-
}
305-
else {
301+
302+
// This _updatePrompt() call is a hack to create a prompt when a new cell is
303+
// added in cellList. Indeed the listener catches that a new cell model is added
304+
// to cellList, but not that the cell widget is created in the NotebookPanel.
305+
// The prompt is a copy of the one from the cell widget but there is no listener
306+
// on its creation. When a new cell is created, it is activated, so we use here
307+
// this activation to create the prompt.
308+
this._updatePrompt();
309+
} else {
306310
this.removeClass(CSS_MOD_ACTIVE);
307311
}
308312
}
309313

310-
// private getCellStateChangedListener(
311-
// srcPrompt: HTMLElement, destPrompt: HTMLElement):
312-
// (model: ICellModel, changedArgs: IChangedArgs<any, any, string>) => void {
313-
// return (model: ICellModel, changedArgs: IChangedArgs<any, any, string>) => {
314-
// if (changedArgs.name == 'executionCount') {
315-
// destPrompt.innerText = srcPrompt.innerText;
316-
// }
317-
// }
318-
// }
314+
/**
315+
* Copy the prompt of the cell widget of the notebook.
316+
*/
317+
private _updatePrompt() {
318+
this._headerElement.removeChild(this._promptNode);
319+
const cell: Cell = this._notebookPanel.content.widgets.find(widget => {
320+
return widget.model.id === this.cellModel.id
321+
});
322+
if (cell && cell.promptNode){
323+
this._promptNode = cell.promptNode.cloneNode(true) as HTMLElement;
324+
} else {
325+
this._promptNode = document.createElement('div');
326+
}
327+
this._headerElement.insertBefore(this._promptNode, this._headerElement.firstChild);
328+
}
329+
330+
private _onStateChange(
331+
model: ICellModel,
332+
changedArgs: IChangedArgs<any, any, string>
333+
) {
334+
if (changedArgs.name == 'executionCount') {
335+
this._updatePrompt();
336+
}
337+
}
319338

320339
private _onMetadataChange (
321340
metadata: IObservableJSON,
@@ -383,6 +402,7 @@ class CellWidget extends Panel {
383402
}
384403
bodyElement.appendChild(fragment);
385404
this.node.appendChild(bodyElement);
405+
this._headerElement = headerElement;
386406
this._lock = headerElement.getElementsByTagName('a')[0];
387407
this._gradeId = idElement;
388408
this._points = pointsElement;
@@ -403,12 +423,8 @@ class CellWidget extends Panel {
403423
private _newHeaderElement(): HTMLDivElement {
404424
const element = document.createElement('div');
405425
element.className = CSS_CELL_HEADER;
406-
// if (this.cell && this.cell.promptNode) {
407-
// const promptNode = this.cell.promptNode.cloneNode(true) as HTMLElement;
408-
// element.appendChild(promptNode);
409-
// this.cell.stateChanged.connect(this.getCellStateChangedListener(
410-
// this.cell.promptNode, promptNode));
411-
// }
426+
this._promptNode = document.createElement('div');
427+
element.appendChild(this._promptNode);
412428
const lockElement = document.createElement('a');
413429
lockElement.className = CSS_LOCK_BUTTON;
414430
const listElement = document.createElement('li');
@@ -552,6 +568,9 @@ class CellWidget extends Panel {
552568
}
553569

554570
private _cellModel: ICellModel;
571+
private _notebookPanel: NotebookPanel | null;
572+
private _promptNode: HTMLElement;
573+
private _headerElement: HTMLDivElement;
555574
private _click = new Signal<this, void>(this);
556575
private _lock: HTMLAnchorElement;
557576
private _gradeId: HTMLDivElement;
@@ -621,7 +640,7 @@ class NotebookWidget extends Panel {
621640

622641
constructor(panel: NotebookPanel) {
623642
super();
624-
this._activeCell = panel.content.activeCell.model;
643+
this._activeCellModel = panel.content.activeCell.model;
625644
this._notebookPanel = panel;
626645
this.addClass(CSS_NOTEBOOK_WIDGET);
627646
this._initCellWidgets(panel.content);
@@ -654,7 +673,7 @@ class NotebookWidget extends Panel {
654673
this.notebookPanel?.disposed?.disconnect(this._onNotebookDisposed, this);
655674

656675
this.notebookPanel?.dispose();
657-
this._activeCell = null;
676+
this._activeCellModel = null;
658677
this._cellMetadataChanged = null;
659678
this._cellWidgets = null;
660679
this._metadataChangedHandlers = null;
@@ -682,7 +701,7 @@ class NotebookWidget extends Panel {
682701
) {
683702
switch (args.type) {
684703
case 'add': {
685-
this._addCellWidget(args.newValues[0], args.newIndex);
704+
this._addCellWidget(args.newValues[0], args.newIndex);
686705
break;
687706
}
688707
case 'move': {
@@ -703,18 +722,18 @@ class NotebookWidget extends Panel {
703722
this._cellWidgets.get(oldCell).dispose();
704723
this._cellWidgets.delete(oldCell);
705724
const cellWidget = this._addCellWidget(newCell, args.newIndex);
706-
cellWidget.setActive(this._activeCell === newCell);
707-
if (this._activeCell === newCell) {
725+
cellWidget.setActive(this._activeCellModel === newCell);
726+
if (this._activeCellModel === newCell) {
708727
this._scrollIntoViewNearest(cellWidget);
709728
}
710729
}
711730
}
712731
}
713732
}
714733

715-
private _addCellWidget(cell: ICellModel, index = undefined as number): CellWidget {
716-
const cellWidget = new CellWidget(cell);
717-
this._cellWidgets.set(cell, cellWidget);
734+
private _addCellWidget(cellModel: ICellModel, index = undefined as number): CellWidget {
735+
const cellWidget = new CellWidget(cellModel, this._notebookPanel);
736+
this._cellWidgets.set(cellModel, cellWidget);
718737
if (index == null) {
719738
this.addWidget(cellWidget);
720739
}
@@ -723,7 +742,7 @@ class NotebookWidget extends Panel {
723742
}
724743
cellWidget.click.connect(this._activeCellWidgetListener, this);
725744
const metadataChangedHandler = this._getMetadataChangedHandler(cellWidget);
726-
cell.metadata.changed.connect(metadataChangedHandler);
745+
cellModel.metadata.changed.connect(metadataChangedHandler);
727746
this._metadataChangedHandlers.set(cellWidget, metadataChangedHandler);
728747
return cellWidget;
729748
}
@@ -741,21 +760,22 @@ class NotebookWidget extends Panel {
741760
/**
742761
* Called when the selected cell on notebook panel changes.
743762
*/
744-
private _onActiveCellChange(notebook: Notebook, cell: Cell) {
745-
if (this._activeCell != null) {
746-
const activeWidget = this._cellWidgets.get(this._activeCell);
763+
private async _onActiveCellChange(notebook: Notebook, cell: Cell) {
764+
if (this._activeCellModel != null) {
765+
const activeWidget = this._cellWidgets.get(this._activeCellModel);
747766
if (activeWidget != null) {
748767
activeWidget.setActive(false);
749768
}
750769
}
751770
if (cell != null) {
771+
await cell.ready;
752772
const activeWidget = this._cellWidgets.get(cell.model);
753773
if (activeWidget != null) {
754774
activeWidget.setActive(true);
755775
this._scrollIntoViewNearest(activeWidget);
756776
}
757777
}
758-
this._activeCell = cell.model;
778+
this._activeCellModel = cell.model;
759779
}
760780

761781
/**
@@ -913,7 +933,7 @@ class NotebookWidget extends Panel {
913933
}
914934
}
915935

916-
private _activeCell = null as ICellModel;
936+
private _activeCellModel = null as ICellModel;
917937
private _cellMetadataChanged = new Signal<this, CellWidget>(this);
918938
private _cellWidgets = new Map<ICellModel, CellWidget>();
919939
private _metadataChangedHandlers = new Map<

0 commit comments

Comments
 (0)