From e6f2a6d33401b54ef3556490779eb2120b5e6069 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Wed, 15 May 2019 13:41:10 -0400 Subject: [PATCH 1/3] test selecting skips collapsed cells --- tests/test-notebook/src/actions.spec.ts | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/test-notebook/src/actions.spec.ts b/tests/test-notebook/src/actions.spec.ts index c6f2bb335cf1..5eea0de19599 100644 --- a/tests/test-notebook/src/actions.spec.ts +++ b/tests/test-notebook/src/actions.spec.ts @@ -823,6 +823,26 @@ describe('@jupyterlab/notebook', () => { NotebookActions.selectAbove(widget); expect(widget.mode).to.equal('edit'); }); + + it('should skip collapsed cells in edit mode', () => { + widget.activeCellIndex = 3; + widget.mode = 'edit'; + widget.widgets[1].inputHidden = true; + widget.widgets[2].inputHidden = true; + widget.widgets[3].inputHidden = false; + NotebookActions.selectAbove(widget); + expect(widget.activeCellIndex).to.equal(0); + }); + + it('should not skip collapsed cells and in command mode', () => { + widget.activeCellIndex = 3; + widget.mode = 'command'; + widget.widgets[1].inputHidden = true; + widget.widgets[2].inputHidden = true; + widget.widgets[3].inputHidden = false; + NotebookActions.selectAbove(widget); + expect(widget.activeCellIndex).to.equal(2); + }); }); describe('#selectBelow()', () => { @@ -851,6 +871,24 @@ describe('@jupyterlab/notebook', () => { NotebookActions.selectBelow(widget); expect(widget.mode).to.equal('edit'); }); + + it('should skip collapsed cells in edit mode', () => { + widget.activeCellIndex = 0; + widget.mode = 'edit'; + widget.widgets[1].inputHidden = true; + widget.widgets[2].inputHidden = true; + widget.widgets[3].inputHidden = false; + NotebookActions.selectBelow(widget); + expect(widget.activeCellIndex).to.equal(4); + }); + + it('should not skip collapsed cells and in command mode', () => { + widget.activeCellIndex = 0; + widget.mode = 'command'; + widget.widgets[1].inputHidden = true; + NotebookActions.selectBelow(widget); + expect(widget.activeCellIndex).to.equal(1); + }); }); describe('#extendSelectionAbove()', () => { From 5a846eee25a1d390b14a54612b07acb5909cf369 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Wed, 15 May 2019 13:47:15 -0400 Subject: [PATCH 2/3] test no-wrapping --- tests/test-notebook/src/actions.spec.ts | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/test-notebook/src/actions.spec.ts b/tests/test-notebook/src/actions.spec.ts index 5eea0de19599..64b17096e763 100644 --- a/tests/test-notebook/src/actions.spec.ts +++ b/tests/test-notebook/src/actions.spec.ts @@ -834,6 +834,14 @@ describe('@jupyterlab/notebook', () => { expect(widget.activeCellIndex).to.equal(0); }); + it('should not change if in edit mode and no non-collapsed cells above', () => { + widget.activeCellIndex = 1; + widget.mode = 'edit'; + widget.widgets[0].inputHidden = true; + NotebookActions.selectAbove(widget); + expect(widget.activeCellIndex).to.equal(1); + }); + it('should not skip collapsed cells and in command mode', () => { widget.activeCellIndex = 3; widget.mode = 'command'; @@ -882,12 +890,22 @@ describe('@jupyterlab/notebook', () => { expect(widget.activeCellIndex).to.equal(4); }); - it('should not skip collapsed cells and in command mode', () => { + it('should not change if in edit mode and no non-collapsed cells below', () => { widget.activeCellIndex = 0; - widget.mode = 'command'; + widget.mode = 'edit'; widget.widgets[1].inputHidden = true; + widget.widgets[2].inputHidden = true; + widget.widgets[3].inputHidden = false; NotebookActions.selectBelow(widget); - expect(widget.activeCellIndex).to.equal(1); + expect(widget.activeCellIndex).to.equal(4); + }); + + it('should not skip collapsed cells and in command mode', () => { + widget.activeCellIndex = widget.widgets.length - 2; + widget.mode = 'edit'; + widget.widgets[widget.widgets.length - 1].inputHidden = true; + NotebookActions.selectBelow(widget); + expect(widget.activeCellIndex).to.equal(widget.widgets.length - 2); }); }); From 8e8ce16d2fc8098c98baf71b10d66dd9253e6879 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Wed, 15 May 2019 14:11:01 -0400 Subject: [PATCH 3/3] fix tests and implement code changes to skip collapsed cells --- packages/notebook/src/actions.tsx | 35 ++++++++++++++++++++++--- tests/test-notebook/src/actions.spec.ts | 22 ++++++++-------- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/packages/notebook/src/actions.tsx b/packages/notebook/src/actions.tsx index e44d9353c463..41e3c48da52e 100644 --- a/packages/notebook/src/actions.tsx +++ b/packages/notebook/src/actions.tsx @@ -644,6 +644,7 @@ export namespace NotebookActions { * #### Notes * The widget mode will be preserved. * This is a no-op if the first cell is the active cell. + * This will skip any collapsed cells. * The existing selection will be cleared. */ export function selectAbove(notebook: Notebook): void { @@ -654,9 +655,22 @@ export namespace NotebookActions { return; } + let possibleNextCell = notebook.activeCellIndex - 1; + + // find first non hidden cell above current cell + if (notebook.mode === 'edit') { + while (notebook.widgets[possibleNextCell].inputHidden) { + // If we are at the top cell, we cannot change selection. + if (possibleNextCell === 0) { + return; + } + possibleNextCell -= 1; + } + } + const state = Private.getState(notebook); - notebook.activeCellIndex -= 1; + notebook.activeCellIndex = possibleNextCell; notebook.deselectAll(); Private.handleState(notebook, state, true); } @@ -669,19 +683,34 @@ export namespace NotebookActions { * #### Notes * The widget mode will be preserved. * This is a no-op if the last cell is the active cell. + * This will skip any collapsed cells. * The existing selection will be cleared. */ export function selectBelow(notebook: Notebook): void { if (!notebook.model || !notebook.activeCell) { return; } - if (notebook.activeCellIndex === notebook.widgets.length - 1) { + const maxCellIndex = notebook.widgets.length - 1; + if (notebook.activeCellIndex === maxCellIndex) { return; } + let possibleNextCell = notebook.activeCellIndex + 1; + + // find first non hidden cell below current cell + if (notebook.mode === 'edit') { + while (notebook.widgets[possibleNextCell].inputHidden) { + // If we are at the bottom cell, we cannot change selection. + if (possibleNextCell === maxCellIndex) { + return; + } + possibleNextCell += 1; + } + } + const state = Private.getState(notebook); - notebook.activeCellIndex += 1; + notebook.activeCellIndex = possibleNextCell; notebook.deselectAll(); Private.handleState(notebook, state, true); } diff --git a/tests/test-notebook/src/actions.spec.ts b/tests/test-notebook/src/actions.spec.ts index 64b17096e763..547071b529a6 100644 --- a/tests/test-notebook/src/actions.spec.ts +++ b/tests/test-notebook/src/actions.spec.ts @@ -797,7 +797,7 @@ describe('@jupyterlab/notebook', () => { }).timeout(60000); // Allow for slower CI }); - describe('#selectAbove(`)', () => { + describe('#selectAbove()', () => { it('should select the cell above the active cell', () => { widget.activeCellIndex = 1; NotebookActions.selectAbove(widget); @@ -887,25 +887,25 @@ describe('@jupyterlab/notebook', () => { widget.widgets[2].inputHidden = true; widget.widgets[3].inputHidden = false; NotebookActions.selectBelow(widget); - expect(widget.activeCellIndex).to.equal(4); + expect(widget.activeCellIndex).to.equal(3); }); it('should not change if in edit mode and no non-collapsed cells below', () => { - widget.activeCellIndex = 0; + widget.activeCellIndex = widget.widgets.length - 2; widget.mode = 'edit'; - widget.widgets[1].inputHidden = true; - widget.widgets[2].inputHidden = true; - widget.widgets[3].inputHidden = false; + widget.widgets[widget.widgets.length - 1].inputHidden = true; NotebookActions.selectBelow(widget); - expect(widget.activeCellIndex).to.equal(4); + expect(widget.activeCellIndex).to.equal(widget.widgets.length - 2); }); it('should not skip collapsed cells and in command mode', () => { - widget.activeCellIndex = widget.widgets.length - 2; - widget.mode = 'edit'; - widget.widgets[widget.widgets.length - 1].inputHidden = true; + widget.activeCellIndex = 0; + widget.mode = 'command'; + widget.widgets[1].inputHidden = true; + widget.widgets[2].inputHidden = true; + widget.widgets[3].inputHidden = false; NotebookActions.selectBelow(widget); - expect(widget.activeCellIndex).to.equal(widget.widgets.length - 2); + expect(widget.activeCellIndex).to.equal(1); }); });