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

Commit 1e8d02b

Browse files
authored
Merge pull request #122 from ckeditor/t/117
Fix: Fixed an error where using spellchecker on a word with a style applied sometimes resulted in that word being removed. Closes #117.
2 parents 9a5e22b + b3ba937 commit 1e8d02b

File tree

2 files changed

+83
-8
lines changed

2 files changed

+83
-8
lines changed

src/input.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -408,9 +408,10 @@ function getMutationsContainer( mutations ) {
408408
.find( element => element.is( 'containerElement' ) || element.is( 'rootElement' ) );
409409
}
410410

411-
// Returns true if container children have mutated and more than a single text node was changed. Single text node
412-
// child insertion is handled in {@link module:typing/input~MutationHandler#_handleTextNodeInsertion} and text
413-
// mutation is handled in {@link module:typing/input~MutationHandler#_handleTextMutation}.
411+
// Returns true if container children have mutated or more than a single text node was changed.
412+
//
413+
// Single text node child insertion is handled in {@link module:typing/input~MutationHandler#_handleTextNodeInsertion}
414+
// while text mutation is handled in {@link module:typing/input~MutationHandler#_handleTextMutation}.
414415
//
415416
// @private
416417
// @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|
@@ -421,14 +422,14 @@ function containerChildrenMutated( mutations ) {
421422
return false;
422423
}
423424

424-
// Check if all mutations are `children` type, and there is no single text node mutation.
425+
// Check if there is any mutation of `children` type or any mutation that changes more than one text node.
425426
for ( const mutation of mutations ) {
426-
if ( mutation.type !== 'children' || getSingleTextNodeChange( mutation ) ) {
427-
return false;
427+
if ( mutation.type === 'children' && !getSingleTextNodeChange( mutation ) ) {
428+
return true;
428429
}
429430
}
430431

431-
return true;
432+
return false;
432433
}
433434

434435
// Returns true if provided array contains only {@link module:engine/model/text~Text model text nodes}.

tests/input.js

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe( 'Input feature', () => {
4141

4242
return VirtualTestEditor
4343
.create( {
44-
plugins: [ Input, Paragraph ]
44+
plugins: [ Input, Paragraph, Bold ]
4545
} )
4646
.then( newEditor => {
4747
// Mock image feature.
@@ -126,6 +126,50 @@ describe( 'Input feature', () => {
126126
expect( getViewData( view ) ).to.equal( '<p>x{}</p>' );
127127
} );
128128

129+
it( 'should handle multiple text mutations', () => {
130+
editor.setData( '<p>foo<strong>bar</strong></p>' );
131+
132+
view.fire( 'mutations', [
133+
{
134+
type: 'text',
135+
oldText: 'foo',
136+
newText: 'foob',
137+
node: viewRoot.getChild( 0 ).getChild( 0 )
138+
},
139+
{
140+
type: 'text',
141+
oldText: 'bar',
142+
newText: 'ar',
143+
node: viewRoot.getChild( 0 ).getChild( 1 ).getChild( 0 )
144+
}
145+
] );
146+
147+
expect( getModelData( model ) ).to.equal( '<paragraph>foob[]<$text bold="true">ar</$text></paragraph>' );
148+
expect( getViewData( view ) ).to.equal( '<p>foob{}<strong>ar</strong></p>' );
149+
} );
150+
151+
it( 'should handle multiple text node insertion', () => {
152+
editor.setData( '<p></p><p></p>' );
153+
154+
view.fire( 'mutations', [
155+
{
156+
type: 'children',
157+
oldChildren: [],
158+
newChildren: [ new ViewText( 'x' ) ],
159+
node: viewRoot.getChild( 0 )
160+
},
161+
{
162+
type: 'children',
163+
oldChildren: [],
164+
newChildren: [ new ViewText( 'y' ) ],
165+
node: viewRoot.getChild( 1 )
166+
}
167+
] );
168+
169+
expect( getModelData( model ) ).to.equal( '<paragraph>x</paragraph><paragraph>y[]</paragraph>' );
170+
expect( getViewData( view ) ).to.equal( '<p>x</p><p>y{}</p>' );
171+
} );
172+
129173
it( 'should do nothing when two nodes were inserted', () => {
130174
editor.setData( '<p></p>' );
131175

@@ -947,6 +991,36 @@ describe( 'Input feature', () => {
947991
expect( getModelData( model ) ).to.equal( '<paragraph><$text bold="true">[]textx</$text></paragraph>' );
948992
expect( getViewData( view ) ).to.equal( '<p><strong>{}textx</strong></p>' );
949993
} );
994+
995+
// #117.
996+
it( 'should handle mixed mutations', () => {
997+
setModelData( model, '<paragraph><$text bold="true">Foo bar aple</$text></paragraph>' );
998+
999+
const paragraph = viewRoot.getChild( 0 );
1000+
const strong = paragraph.getChild( 0 );
1001+
const viewSelection = new ViewSelection();
1002+
viewSelection.setCollapsedAt( paragraph, 0 );
1003+
1004+
// Simulate mutations and DOM change.
1005+
domRoot.childNodes[ 0 ].innerHTML = '<strong>Foo bar </strong><b>apple</b>';
1006+
view.fire( 'mutations', [
1007+
{
1008+
type: 'text',
1009+
oldText: 'Foo bar aple',
1010+
newText: 'Foo bar ',
1011+
node: viewRoot.getChild( 0 ).getChild( 0 )
1012+
},
1013+
{
1014+
type: 'children',
1015+
oldChildren: [ strong ],
1016+
newChildren: [ strong, new ViewElement( 'b', null, new ViewText( 'apple' ) ) ],
1017+
node: paragraph
1018+
}
1019+
], viewSelection );
1020+
1021+
expect( getModelData( model ) ).to.equal( '<paragraph><$text bold="true">[]Foo bar apple</$text></paragraph>' );
1022+
expect( getViewData( view ) ).to.equal( '<p><strong>{}Foo bar apple</strong></p>' );
1023+
} );
9501024
} );
9511025
} );
9521026

0 commit comments

Comments
 (0)