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

Commit c698683

Browse files
committedSep 9, 2019
Merge pull request #1783 from mycolorway:t/ckeditor5/1333.
Fix: The renderer shouold not update DOM selection when document has active composition. Closes #1782. Closes ckeditor/ckeditor5#1333.
2 parents 62fe3e1 + 427ee66 commit c698683

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed
 

‎src/view/renderer.js

+12
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ export default class Renderer {
101101
*/
102102
this.isFocused = false;
103103

104+
/**
105+
* Indicates if the composition is in progress inside the view document view.
106+
*
107+
* @member {Boolean}
108+
*/
109+
this.isComposing = false;
110+
104111
/**
105112
* The text node in which the inline filler was rendered.
106113
*
@@ -771,6 +778,11 @@ export default class Renderer {
771778
* @returns {Boolean}
772779
*/
773780
_domSelectionNeedsUpdate( domSelection ) {
781+
// Remain DOM selection untouched while composing. See #1782.
782+
if ( this.isComposing ) {
783+
return false;
784+
}
785+
774786
if ( !this.domConverter.isDomSelectionCorrect( domSelection ) ) {
775787
// Current DOM selection is in incorrect position. We need to update it.
776788
return true;

‎src/view/view.js

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export default class View {
105105
*/
106106
this._renderer = new Renderer( this.domConverter, this.document.selection );
107107
this._renderer.bind( 'isFocused' ).to( this.document );
108+
this._renderer.bind( 'isComposing' ).to( this.document );
108109

109110
/**
110111
* A DOM root attributes cache. It saves the initial values of DOM root attributes before the DOM element

‎tests/view/renderer.js

+42
Original file line numberDiff line numberDiff line change
@@ -3641,6 +3641,48 @@ describe( 'Renderer', () => {
36413641
return viewData.repeat( repeat );
36423642
}
36433643
} );
3644+
3645+
// #1782
3646+
it( 'should leave dom selection untouched while composing', () => {
3647+
const { view: viewP, selection: newSelection } = parse( '<container:p>[]</container:p>' );
3648+
3649+
viewRoot._appendChild( viewP );
3650+
selection._setTo( newSelection );
3651+
3652+
renderer.markToSync( 'children', viewRoot );
3653+
renderer.render();
3654+
3655+
// Mock IME typing in Safari: <p>[c]</p>.
3656+
renderer.isComposing = true;
3657+
const domText = document.createTextNode( 'c' );
3658+
domRoot.firstChild.appendChild( domText );
3659+
const range = document.createRange();
3660+
range.setStart( domText, 0 );
3661+
range.setEnd( domText, 1 );
3662+
const domSelection = document.getSelection();
3663+
domSelection.removeAllRanges();
3664+
domSelection.addRange( range );
3665+
3666+
// <container:p>c[]</container:p>
3667+
viewP._appendChild( new ViewText( 'c' ) );
3668+
selection._setTo( [
3669+
new ViewRange( new ViewPosition( viewP.getChild( 0 ), 1 ), new ViewPosition( viewP.getChild( 0 ), 1 ) )
3670+
] );
3671+
3672+
renderer.markToSync( 'children', viewP );
3673+
renderer.render();
3674+
3675+
expect( domRoot.childNodes.length ).to.equal( 1 );
3676+
expect( domRoot.firstChild.childNodes.length ).to.equal( 1 );
3677+
expect( domRoot.firstChild.firstChild.data ).to.equal( 'c' );
3678+
3679+
const currentRange = domSelection.getRangeAt( 0 );
3680+
expect( currentRange.collapsed ).to.equal( false );
3681+
expect( currentRange.startContainer ).to.equal( domRoot.firstChild.firstChild );
3682+
expect( currentRange.startOffset ).to.equal( 0 );
3683+
expect( currentRange.endContainer ).to.equal( domRoot.firstChild.firstChild );
3684+
expect( currentRange.endOffset ).to.equal( 1 );
3685+
} );
36443686
} );
36453687

36463688
describe( '#922', () => {

0 commit comments

Comments
 (0)
This repository has been archived.