Sfoglia il codice sorgente

Fixed: Renderer should remove inline filler if selection is before a view element not bound to DOM.

Szymon Cofalik 9 anni fa
parent
commit
37d89d19f3

+ 5 - 3
packages/ckeditor5-engine/src/view/renderer.js

@@ -304,10 +304,12 @@ export default class Renderer {
 			return false;
 		}
 
-		const { parent: domParent } = this.domConverter.viewPositionToDom( selectionPosition );
+		const position = this.domConverter.viewPositionToDom( selectionPosition );
 
-		if ( this.domConverter.isText( domParent ) && startsWithFiller( domParent ) ) {
-			return true;
+		if ( position ) {
+			if ( this.domConverter.isText( position.parent ) && startsWithFiller( position.parent ) ) {
+				return true;
+			}
 		}
 
 		return false;

+ 31 - 0
packages/ckeditor5-engine/tests/view/renderer.js

@@ -683,6 +683,37 @@ describe( 'Renderer', () => {
 			expect( domP.childNodes[ 1 ].childNodes[ 0 ].data ).to.equal( INLINE_FILLER );
 		} );
 
+		// Test for an edge case in the _isSelectionInInlineFiller, when selection is before a view element
+		// that has not been yet rendered/bound to DOM.
+		it( 'should remove inline filler if selection is before a view element not bound to dom', () => {
+			// Step 1: <p>bar<b>abc</b>"FILLER"{}</p>
+			const { view: viewP, selection: newSelection } = parse( '<container:p>bar<attribute:b>abc</attribute:b>[]</container:p>' );
+			viewRoot.appendChildren( viewP );
+			selection.setTo( newSelection );
+
+			renderer.markToSync( 'children', viewRoot );
+			renderer.render();
+
+			const domP = domRoot.childNodes[ 0 ];
+			expect( domP.childNodes.length ).to.equal( 3 );
+			expect( domP.childNodes[ 2 ].data ).to.equal( INLINE_FILLER );
+
+			// Step 2: Move selection to a new attribute element.
+			const viewI = parse( '<attribute:i>abc</attribute:i>' );
+			viewP.appendChildren( viewI );
+
+			selection.removeAllRanges();
+			selection.addRange( ViewRange.createFromParentsAndOffsets( viewP, 3, viewP, 3 ) );
+
+			renderer.markToSync( 'children', viewP );
+			renderer.markToSync( 'children', viewI );
+			renderer.render();
+
+			// Step 3: Check whether old filler was removed.
+			expect( domP.childNodes.length ).to.equal( 3 );
+			expect( domP.textContent.indexOf( INLINE_FILLER ) ).to.equal( -1 );
+		} );
+
 		it( 'should handle typing in empty block, do nothing if changes are already applied', () => {
 			const domSelection = document.getSelection();