Aleksander Nowodzinski hace 5 años
padre
commit
543d8a3529

+ 0 - 48
packages/ckeditor5-widget/src/widget.js

@@ -12,7 +12,6 @@ import MouseObserver from '@ckeditor/ckeditor5-engine/src/view/observer/mouseobs
 import WidgetTypeAround from './widgettypearound/widgettypearound';
 import { getLabel, isWidget, WIDGET_SELECTED_CLASS_NAME } from './utils';
 import {
-	keyCodes,
 	isArrowKeyCode,
 	isForwardArrowKeyCode
 } from '@ckeditor/ckeditor5-utils/src/keyboard';
@@ -182,8 +181,6 @@ export default class Widget extends Plugin {
 			const isForward = isForwardArrowKeyCode( keyCode, this.editor.locale.contentLanguageDirection );
 
 			wasHandled = this._handleArrowKeys( isForward );
-		} else if ( keyCode === keyCodes.enter ) {
-			wasHandled = this._handleEnterKey( domEventData.shiftKey );
 		}
 
 		if ( wasHandled ) {
@@ -277,43 +274,6 @@ export default class Widget extends Plugin {
 		}
 	}
 
-	/**
-	 * Handles the enter key, giving users and access to positions in the editable directly before
-	 * (<kbd>Shift</kbd>+<kbd>Enter</kbd>) or after (<kbd>Enter</kbd>) the selected widget.
-	 * It improves the UX, mainly when the widget is the first or last child of the root editable
-	 * and there's no other way to type after or before it.
-	 *
-	 * @private
-	 * @param {Boolean} isBackwards Set to true if the new paragraph is to be inserted before
-	 * the selected widget (<kbd>Shift</kbd>+<kbd>Enter</kbd>).
-	 * @returns {Boolean|undefined} Returns `true` if keys were handled correctly.
-	 */
-	_handleEnterKey( isBackwards ) {
-		const model = this.editor.model;
-		const modelSelection = model.document.selection;
-		const selectedElement = modelSelection.getSelectedElement();
-
-		if ( shouldInsertParagraph( selectedElement, model.schema ) ) {
-			model.change( writer => {
-				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.isBlock( selectedElement.parent ) ) {
-					const paragraphLimit = model.schema.findAllowedParent( position, paragraph );
-
-					position = writer.split( position, paragraphLimit ).position;
-				}
-
-				writer.insert( paragraph, position );
-				writer.setSelection( paragraph, 'in' );
-			} );
-
-			return true;
-		}
-	}
-
 	/**
 	 * Sets {@link module:engine/model/selection~Selection document's selection} over given element.
 	 *
@@ -401,11 +361,3 @@ 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 );
-}

+ 48 - 6
packages/ckeditor5-widget/src/widgettypearound/widgettypearound.js

@@ -97,6 +97,7 @@ export default class WidgetTypeAround extends Plugin {
 		this._enableTypeAroundUIInjection();
 		this._enableDetectionOfTypeAroundWidgets();
 		this._enableInsertingParagraphsOnButtonClick();
+		this._enableInsertingParagraphsOnEnterKeypress();
 		this._enableTypeAroundActivationUsingKeyboardArrows();
 
 		// TODO: This is a quick fix and it should be removed the proper integration arrives.
@@ -334,37 +335,51 @@ export default class WidgetTypeAround extends Plugin {
 
 				if ( shouldStopAndPreventDefault ) {
 					domEventData.preventDefault();
-					domEventData.stopPropagation();
 					evt.stop();
 				}
 			} );
 		}, { priority: priorities.get( 'high' ) + 1 } );
 
 		modelSelection.on( 'change:range', () => {
-			const editor = this.editor;
-			const model = editor.model;
-			const modelSelection = model.document.selection;
-
 			if ( !modelSelection.hasAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE ) ) {
 				return;
 			}
 
+			// Get rid of the widget type around attribute of the selection on every change:range.
+			// If the range changes, it means for sure, the user is no longer in the active ("blinking line") mode.
 			editor.model.change( writer => {
 				// TODO: use data.directChange to not break collaboration?
 				writer.removeSelectionAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE );
 			} );
+
+			// Also, if the range changes, get rid of CSS classes associated with the active ("blinking line") mode.
+			// There's no way to do that in the "selection" downcast dispatcher because it is executed too late.
+			editingView.change( writer => {
+				const selectedViewElement = editingView.document.selection.getSelectedElement();
+
+				writer.removeClass( POSSIBLE_INSERTION_POSITIONS.map( positionToWidgetCssClass ), selectedViewElement );
+			} );
 		} );
 
+		// React to changes of the mode selection attribute made by the arrow keys listener.
+		// If the block widget is selected and the attribute changes, downcast the attribute to special
+		// CSS classes associated with the active ("blinking line") mode of the widget.
 		editor.editing.downcastDispatcher.on( 'selection', ( evt, data, conversionApi ) => {
 			const writer = conversionApi.writer;
 			const selectedModelElement = data.selection.getSelectedElement();
+
+			if ( !selectedModelElement ) {
+				return;
+			}
+
 			const selectedViewElement = conversionApi.mapper.toViewElement( selectedModelElement );
-			const typeAroundSelectionAttribute = data.selection.getAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE );
 
 			if ( !isTypeAroundWidget( selectedViewElement, selectedModelElement, schema ) ) {
 				return;
 			}
 
+			const typeAroundSelectionAttribute = data.selection.getAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE );
+
 			if ( typeAroundSelectionAttribute ) {
 				writer.addClass( positionToWidgetCssClass( typeAroundSelectionAttribute ), selectedViewElement );
 			} else {
@@ -376,6 +391,33 @@ export default class WidgetTypeAround extends Plugin {
 			return `ck-widget_type-around_active_${ position }`;
 		}
 	}
+
+	/**
+	 * TODO
+	 *
+	 * @private
+	 */
+	_enableInsertingParagraphsOnEnterKeypress() {
+		const editor = this.editor;
+		const model = editor.model;
+		const modelSelection = model.document.selection;
+		const editingView = editor.editing.view;
+
+		this.listenTo( editingView.document, 'enter', ( evt, domEventData ) => {
+			const typeAroundSelectionAttribute = modelSelection.getAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE );
+
+			if ( !typeAroundSelectionAttribute ) {
+				return;
+			}
+
+			const selectedViewElement = editingView.document.selection.getSelectedElement();
+
+			this._insertParagraph( selectedViewElement, typeAroundSelectionAttribute );
+
+			domEventData.preventDefault();
+			evt.stop();
+		} );
+	}
 }
 
 // Injects the type around UI into a view widget instance.