Procházet zdrojové kódy

Merge pull request #78 from ckeditor/t/77

Fix: It should be possible to type before a mention which is at the beginning of a block. Closes #77.
Piotrek Koszuliński před 6 roky
rodič
revize
8383078374

+ 15 - 5
packages/ckeditor5-mention/src/mentionediting.js

@@ -149,7 +149,8 @@ function createViewMentionElement( mention, viewWriter ) {
 	return viewWriter.createAttributeElement( 'span', attributes, options );
 }
 
-// Model post-fixer that disallows typing with selection when the selection is placed after the text node with the mention attribute.
+// Model post-fixer that disallows typing with selection when the selection is placed after the text node with the mention attribute or
+// before a text node with mention attribute.
 //
 // @param {module:engine/model/writer~Writer} writer
 // @param {module:engine/model/document~Document} doc
@@ -158,15 +159,24 @@ function selectionMentionAttributePostFixer( writer, doc ) {
 	const selection = doc.selection;
 	const focus = selection.focus;
 
-	if ( selection.isCollapsed && selection.hasAttribute( 'mention' ) && isNodeBeforeAText( focus ) ) {
+	if ( selection.isCollapsed && selection.hasAttribute( 'mention' ) && shouldNotTypeWithMentionAt( focus ) ) {
 		writer.removeSelectionAttribute( 'mention' );
 
 		return true;
 	}
+}
 
-	function isNodeBeforeAText( position ) {
-		return position.nodeBefore && position.nodeBefore.is( 'text' );
-	}
+// Helper function to detect if mention attribute should be removed from selection.
+// This check makes only sense if the selection has mention attribute.
+//
+// The mention attribute should be removed from a selection when selection focus is placed:
+// a) after a text node
+// b) the position is at parents start - the selection will set attributes from node after.
+function shouldNotTypeWithMentionAt( position ) {
+	const isAtStart = position.isAtStart;
+	const isAfterAMention = position.nodeBefore && position.nodeBefore.is( 'text' );
+
+	return isAfterAMention || isAtStart;
 }
 
 // Model post-fixer that removes the mention attribute from the modified text node.

+ 19 - 0
packages/ckeditor5-mention/tests/mentionediting.js

@@ -272,6 +272,25 @@ describe( 'MentionEditing', () => {
 
 			expect( editor.getData() ).to.equal( '<p>foo <span class="mention" data-mention="@John">@John</span> bar</p>' );
 		} );
+
+		it( 'should not allow to type with mention attribute before mention', () => {
+			editor.setData( '<p><span class="mention" data-mention="@John">@John</span> bar</p>' );
+
+			const paragraph = doc.getRoot().getChild( 0 );
+
+			// Set selection before mention.
+			model.change( writer => {
+				writer.setSelection( paragraph, 0 );
+			} );
+
+			expect( Array.from( doc.selection.getAttributes() ) ).to.deep.equal( [] );
+
+			model.change( writer => {
+				writer.insertText( 'a', doc.selection.getAttributes(), writer.createPositionAt( paragraph, 0 ) );
+			} );
+
+			expect( editor.getData() ).to.equal( '<p>a<span class="mention" data-mention="@John">@John</span> bar</p>' );
+		} );
 	} );
 
 	describe( 'removing partial mention post-fixer', () => {