Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge pull request #78 from ckeditor/t/77
Browse files Browse the repository at this point in the history
Fix: It should be possible to type before a mention which is at the beginning of a block. Closes #77.
  • Loading branch information
Reinmar authored Jul 1, 2019
2 parents 764f099 + 164c858 commit 946e762
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
20 changes: 15 additions & 5 deletions src/mentionediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down
19 changes: 19 additions & 0 deletions tests/mentionediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down

0 comments on commit 946e762

Please sign in to comment.