Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge pull request #75 from ckeditor/t/ckeditor5/1555
Browse files Browse the repository at this point in the history
Fix: Editor crashes after Enter key on an image that is inside a blockquote. Closes ckeditor/ckeditor5#1555.
  • Loading branch information
oskarwrobel committed Feb 21, 2019
2 parents dad101f + 6dc95c4 commit 8a8842b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
18 changes: 13 additions & 5 deletions src/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ export default class Widget extends Plugin {
*/
_onKeydown( eventInfo, domEventData ) {
const keyCode = domEventData.keyCode;
const isForward = keyCode == keyCodes.delete || keyCode == keyCodes.arrowdown || keyCode == keyCodes.arrowright;
const isForward = keyCode == keyCodes.arrowdown || keyCode == keyCodes.arrowright;
let wasHandled = false;

// Checks if the keys were handled and then prevents the default event behaviour and stops
Expand Down Expand Up @@ -268,16 +268,16 @@ export default class Widget extends Plugin {
_handleEnterKey( isBackwards ) {
const model = this.editor.model;
const modelSelection = model.document.selection;
const objectElement = modelSelection.getSelectedElement();
const selectedElement = modelSelection.getSelectedElement();

if ( objectElement && model.schema.isObject( objectElement ) ) {
if ( shouldInsertParagraph( selectedElement, model.schema ) ) {
model.change( writer => {
let position = writer.createPositionAt( objectElement, isBackwards ? 'before' : 'after' );
let position = writer.createPositionAt( selectedElement, isBackwards ? 'before' : 'after' );
const paragraph = writer.createElement( 'paragraph' );

// Split the parent when inside a block element.
// https://github.com/ckeditor/ckeditor5/issues/1529
if ( !model.schema.isLimit( objectElement.parent ) ) {
if ( model.schema.isBlock( selectedElement.parent ) ) {
const paragraphLimit = model.schema.findAllowedParent( position, paragraph );

position = writer.split( position, paragraphLimit ).position;
Expand Down Expand Up @@ -451,3 +451,11 @@ function isChild( element, parent ) {

return Array.from( element.getAncestors() ).includes( parent );
}

// Checks if enter key should insert paragraph. This should be done only on elements of type object (excluding inline objects).
//
// @param {module:engine/model/element~Element} element And element to check.
// @param {module:engine/model/schema~Schema} schema
function shouldInsertParagraph( element, schema ) {
return element && schema.isObject( element ) && !schema.isInline( element );
}
34 changes: 34 additions & 0 deletions tests/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ describe( 'Widget', () => {
model.schema.register( 'editable', {
allowIn: [ 'widget', '$root' ]
} );
model.schema.register( 'inline-widget', {
allowWhere: '$text',
isObject: true,
isInline: true
} );

// Image feature.
model.schema.register( 'image', {
Expand Down Expand Up @@ -90,6 +95,14 @@ describe( 'Widget', () => {
return toWidget( div, viewWriter, { label: 'element label' } );
}
} )
.elementToElement( {
model: 'inline-widget',
view: ( modelItem, viewWriter ) => {
const span = viewWriter.createContainerElement( 'span' );

return toWidget( span, viewWriter );
}
} )
.elementToElement( {
model: 'nested',
view: ( modelItem, viewWriter ) => viewWriter.createEditableElement( 'figcaption', { contenteditable: true } )
Expand Down Expand Up @@ -761,6 +774,27 @@ describe( 'Widget', () => {
'<allowP><disallowP><widget></widget></disallowP><paragraph>[]</paragraph><disallowP></disallowP></allowP>'
);
} );

test(
'should do nothing if selected is inline object',
'<paragraph>foo[<inline-widget></inline-widget>]bar</paragraph>',
keyCodes.enter,
'<paragraph>foo[]bar</paragraph>'
);

test(
'should insert a paragraph after the selected widget inside an element that is not a block upon Enter',
'<blockQuote>[<widget></widget>]</blockQuote>',
keyCodes.enter,
'<blockQuote><widget></widget><paragraph>[]</paragraph></blockQuote>'
);

test(
'should insert a paragraph before the selected widget inside an element that is not a block upon Shift+Enter',
'<blockQuote>[<widget></widget>]</blockQuote>',
{ keyCode: keyCodes.enter, shiftKey: true },
'<blockQuote><paragraph>[]</paragraph><widget></widget></blockQuote>'
);
} );

function test( name, data, keyCodeOrMock, expected, expectedView ) {
Expand Down

0 comments on commit 8a8842b

Please sign in to comment.