Parcourir la source

Merge pull request #75 from ckeditor/t/ckeditor5/1555

Fix: Editor crashes after Enter key on an image that is inside a blockquote. Closes ckeditor/ckeditor5#1555.
Oskar Wróbel il y a 7 ans
Parent
commit
4e381c1f8f

+ 13 - 5
packages/ckeditor5-widget/src/widget.js

@@ -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
@@ -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;
@@ -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 - 0
packages/ckeditor5-widget/tests/widget.js

@@ -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', {
@@ -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 } )
@@ -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 ) {