ソースを参照

Merge pull request #74 from ckeditor/t/ckeditor5/1529

Fix: Pressing <kbd>Enter</kbd> should split parent element when the inline widget is inside a `$block`. Closes ckeditor/ckeditor5#1529.
Aleksander Nowodzinski 6 年 前
コミット
b2c8f564bf

+ 5 - 0
packages/ckeditor5-widget/package.json

@@ -17,11 +17,16 @@
   },
   "devDependencies": {
     "@ckeditor/ckeditor5-basic-styles": "^10.1.0",
+    "@ckeditor/ckeditor5-clipboard": "^10.0.4",
     "@ckeditor/ckeditor5-editor-balloon": "^11.0.2",
     "@ckeditor/ckeditor5-editor-classic": "^11.0.2",
+    "@ckeditor/ckeditor5-enter": "^10.1.3",
     "@ckeditor/ckeditor5-essentials": "^10.1.3",
+    "@ckeditor/ckeditor5-heading": "^10.1.1",
     "@ckeditor/ckeditor5-paragraph": "^10.0.4",
+    "@ckeditor/ckeditor5-table": "^11.0.1",
     "@ckeditor/ckeditor5-typing": "^11.0.2",
+    "@ckeditor/ckeditor5-undo": "^10.0.4",
     "eslint": "^5.5.0",
     "eslint-config-ckeditor5": "^1.0.9",
     "husky": "^1.3.1",

+ 10 - 1
packages/ckeditor5-widget/src/widget.js

@@ -272,9 +272,18 @@ export default class Widget extends Plugin {
 
 		if ( objectElement && model.schema.isObject( objectElement ) ) {
 			model.change( writer => {
+				let position = writer.createPositionAt( objectElement, isBackwards ? 'before' : 'after' );
 				const paragraph = writer.createElement( 'paragraph' );
 
-				writer.insert( paragraph, objectElement, isBackwards ? 'before' : 'after' );
+				// Split the parent when inside a block element.
+				// https://github.com/ckeditor/ckeditor5/issues/1529
+				if ( !model.schema.isLimit( objectElement.parent ) ) {
+					const paragraphLimit = model.schema.findAllowedParent( position, paragraph );
+
+					position = writer.split( position, paragraphLimit ).position;
+				}
+
+				writer.insert( paragraph, position );
 				writer.setSelection( paragraph, 'in' );
 			} );
 

+ 1 - 1
packages/ckeditor5-widget/tests/manual/inline-widget.js

@@ -16,7 +16,7 @@ import Heading from '@ckeditor/ckeditor5-heading/src/heading';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Typing from '@ckeditor/ckeditor5-typing/src/typing';
 import Undo from '@ckeditor/ckeditor5-undo/src/undo';
-import Widget from '@ckeditor/ckeditor5-widget/src/widget';
+import Widget from '../../src/widget';
 import { toWidget, viewToModelPositionOutsideModelElement } from '../../src/utils';
 import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
 import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard';

+ 33 - 0
packages/ckeditor5-widget/tests/widget.js

@@ -728,6 +728,39 @@ describe( 'Widget', () => {
 				keyCodes.enter,
 				'<paragraph>f[]ar</paragraph>'
 			);
+
+			// https://github.com/ckeditor/ckeditor5/issues/1529
+			it( 'should split parent when widget is inside a block element', () => {
+				model.schema.register( 'allowP', {
+					inheritAllFrom: '$block'
+				} );
+				model.schema.register( 'disallowP', {
+					inheritAllFrom: '$block',
+					allowIn: [ 'allowP' ]
+				} );
+				model.schema.extend( 'widget', {
+					allowIn: [ 'allowP', 'disallowP' ]
+				} );
+				model.schema.extend( 'paragraph', {
+					allowIn: [ 'allowP' ]
+				} );
+
+				editor.conversion.for( 'downcast' ).elementToElement( { model: 'parent', view: 'parent' } );
+				editor.conversion.for( 'downcast' ).elementToElement( { model: 'allowP', view: 'allowP' } );
+				editor.conversion.for( 'downcast' ).elementToElement( { model: 'disallowP', view: 'disallowP' } );
+
+				setModelData( model, '<allowP><disallowP>[<widget></widget>]</disallowP></allowP>' );
+
+				viewDocument.fire( 'keydown', new DomEventData(
+					viewDocument,
+					{ target: document.createElement( 'div' ), preventDefault() {} },
+					{ keyCode: keyCodes.enter }
+				) );
+
+				expect( getModelData( model ) ).to.equal(
+					'<allowP><disallowP><widget></widget></disallowP><paragraph>[]</paragraph><disallowP></disallowP></allowP>'
+				);
+			} );
 		} );
 
 		function test( name, data, keyCodeOrMock, expected, expectedView ) {