Browse Source

Refactoring.

Piotrek Koszuliński 9 years ago
parent
commit
f72ed591e7

+ 45 - 40
packages/ckeditor5-enter/src/entercommand.js

@@ -30,73 +30,78 @@ export function enterBlock( batch, selection, options = {} ) {
 	const defaultBlockName = options.defaultBlockName;
 	const doc = batch.doc;
 	const isSelectionEmpty = selection.isCollapsed;
-
-	if ( isSelectionEmpty ) {
-		const startPos = selection.focus;
-		const startElement = startPos.parent;
-
-		// Don't touch the root.
-		if ( startElement.root == startElement ) {
-			return;
+	const range = selection.getFirstRange();
+	const startElement = range.start.parent;
+	const endElement = range.end.parent;
+
+	// Don't touch the root.
+	if ( startElement.root == startElement ) {
+		if ( !isSelectionEmpty ) {
+			doc.composer.deleteContents( batch, selection );
 		}
 
-		split( startPos );
+		return;
+	}
+
+	if ( isSelectionEmpty ) {
+		splitBlock( batch, selection, range.start, defaultBlockName );
 	} else {
-		const range = selection.getFirstRange();
-		const startElement = range.start.parent;
-		const endElement = range.end.parent;
 		const shouldMerge = range.start.isAtStart() && range.end.isAtEnd();
 		const isContainedWithinOneElement = ( startElement == endElement );
 
 		doc.composer.deleteContents( batch, selection, { merge: shouldMerge } );
 
-		// Don't touch the root.
-		if ( startElement.root == startElement ) {
-			return;
-		}
-
-		const newBlockName = getNewBlockName( doc, startElement, defaultBlockName );
-		const needsRename = startElement.name != newBlockName;
-
 		// Fully selected elements.
 		//
-		// <h>[xx</h><p>yy]<p>	-> <h>^</h>		-> <p>^</p>
-		// <h>[xxyy]</h>		-> <h>^</h>		-> <p>^</p>
+		// <h>[xx</h><p>yy]<p>	-> <h>^</h>				-> <p>^</p>
+		// <h>[xxyy]</h>		-> <h>^</h>				-> <p>^</p>
 		if ( shouldMerge ) {
+			// We'll lose the ref to the renamed element, so let's keep a position inside it
+			// (offsets won't change, so it will stay in place). See ckeditor5-engine#367.
 			const pos = Position.createFromPosition( selection.focus );
+			const newBlockName = getNewBlockName( doc, startElement, defaultBlockName );
 
-			if ( needsRename ) {
+			if ( startElement.name != newBlockName ) {
 				batch.rename( newBlockName, startElement );
 			}
 
 			selection.collapse( pos );
-		} else if ( isContainedWithinOneElement ) {
-			split( selection.focus );
-		} else {
+		}
+		// Partially selected elements.
+		//
+		// <h>x[xx]x</h>		-> <h>x^x</h>			-> <h>x</h><h>^x</h>
+		else if ( isContainedWithinOneElement ) {
+			splitBlock( batch, selection, selection.focus, defaultBlockName );
+		}
+		// Selection over multilpe elements.
+		//
+		// <h>x[x</h><p>y]y<p>	-> <h>x^</h><p>y</p>	-> <h>x</h><p>^y</p>
+		else {
 			selection.collapse( endElement );
 		}
 	}
+}
 
-	function split( splitPos ) {
-		const parent = splitPos.parent;
+function splitBlock( batch, selection, splitPos, defaultBlockName ) {
+	const doc = batch.doc;
+	const parent = splitPos.parent;
 
-		if ( splitPos.isAtEnd() ) {
-			const newElement = new Element( getNewBlockName( doc, parent, defaultBlockName ) );
+	if ( splitPos.isAtEnd() ) {
+		const newElement = new Element( getNewBlockName( doc, parent, defaultBlockName ) );
 
-			batch.insert( Position.createAfter( parent ), newElement );
+		batch.insert( Position.createAfter( parent ), newElement );
 
-			selection.collapse( newElement );
-		} else {
-			// TODO After ckeditor5-engine#340 is fixed we'll be able to base on splitPos's location.
-			const endPos = LivePosition.createFromPosition( splitPos );
-			endPos.stickiness = 'STICKS_TO_NEXT';
+		selection.collapse( newElement );
+	} else {
+		// TODO After ckeditor5-engine#340 is fixed we'll be able to base on splitPos's location.
+		const endPos = LivePosition.createFromPosition( splitPos );
+		endPos.stickiness = 'STICKS_TO_NEXT';
 
-			batch.split( splitPos );
+		batch.split( splitPos );
 
-			selection.collapse( endPos );
+		selection.collapse( endPos );
 
-			endPos.detach();
-		}
+		endPos.detach();
 	}
 }
 

+ 8 - 1
packages/ckeditor5-enter/tests/entercommand.js

@@ -120,6 +120,13 @@ describe( 'EnterCommand', () => {
 			);
 
 			test(
+				'deletes text and splits (other than default)',
+				'<h>ab<selection>cd</selection>ef</h>',
+				'<h>ab</h><h><selection />ef</h>',
+				{ defaultBlockName: 'p' }
+			);
+
+			test(
 				'places selection in the 2nd element',
 				'<h>ab<selection>c</h><p>d</selection>ef</p><p>ghi</p>',
 				'<h>ab</h><p><selection />ef</p><p>ghi</p>',
@@ -148,7 +155,7 @@ describe( 'EnterCommand', () => {
 			);
 
 			test(
-				'leaves one (default) empty element after two were fully selected (bacward)',
+				'leaves one (default) empty element after two were fully selected (backward)',
 				'<h><selection backward>abc</h><p>def</selection></p>',
 				'<p><selection /></p>',
 				{ defaultBlockName: 'p' }