diff --git a/modules/ve/ce/ve.ce.Surface.js b/modules/ve/ce/ve.ce.Surface.js index 7f7a57ccd5..4d49053a80 100644 --- a/modules/ve/ce/ve.ce.Surface.js +++ b/modules/ve/ce/ve.ce.Surface.js @@ -1658,13 +1658,20 @@ ve.ce.Surface.prototype.handleEnter = function ( e ) { // Now we can move the cursor forward if ( advanceCursor ) { - this.model.setSelection( - new ve.Range( documentModel.data.getRelativeContentOffset( selection.from, 1 ) ) - ); + cursor = documentModel.data.getRelativeContentOffset( selection.from, 1 ); } else { - this.model.setSelection( - new ve.Range( documentModel.data.getNearestContentOffset( selection.from ) ) + cursor = documentModel.data.getNearestContentOffset( selection.from ); + } + if ( cursor === -1 ) { + // Cursor couldn't be placed in a nearby content node, so create an empty paragraph + this.model.change( + ve.dm.Transaction.newFromInsertion( + documentModel, selection.from, emptyParagraph + ) ); + this.model.setSelection( new ve.Range( selection.from + 1 ) ); + } else { + this.model.setSelection( new ve.Range( cursor ) ); } // Reset and resume polling this.surfaceObserver.clear(); diff --git a/modules/ve/test/ce/ve.ce.Surface.test.js b/modules/ve/test/ce/ve.ce.Surface.test.js index ed765a11b2..7468978860 100644 --- a/modules/ve/test/ce/ve.ce.Surface.test.js +++ b/modules/ve/test/ce/ve.ce.Surface.test.js @@ -312,6 +312,20 @@ QUnit.test( 'handleEnter', function ( assert ) { }, 'expectedRange': new ve.Range( 1 ), 'msg': 'Enter in an empty list at start of document destroys it and moves to next paragraph' + }, + { + 'html': emptyList, + 'range': new ve.Range( 3 ), + 'operations': ['enter'], + 'expectedData': function ( data ) { + data.splice( + 0, 6, + { 'type': 'paragraph' }, + { 'type': '/paragraph' } + ); + }, + 'expectedRange': new ve.Range( 1 ), + 'msg': 'Enter in an empty list with no adjacent content destroys it and creates a paragraph' } ];