Kaynağa Gözat

Deep text children rerendering.

Krzysztof Krztoń 7 yıl önce
ebeveyn
işleme
29e688cb80

+ 1 - 1
packages/ckeditor5-engine/src/view/observer/mutationobserver.js

@@ -206,7 +206,7 @@ export default class MutationObserver extends Observer {
 		for ( const viewElement of mutatedElements ) {
 			const domElement = domConverter.mapViewToDom( viewElement );
 			const viewChildren = Array.from( viewElement.getChildren() );
-			const newViewChildren = Array.from( domConverter.domChildrenToView( domElement ) );
+			const newViewChildren = Array.from( domConverter.domChildrenToView( domElement, { withChildren: false } ) );
 
 			// It may happen that as a result of many changes (sth was inserted and then removed),
 			// both elements haven't really changed. #1031

+ 27 - 6
packages/ckeditor5-engine/src/view/renderer.js

@@ -198,12 +198,6 @@ export default class Renderer {
 			this.markedChildren.add( inlineFillerPosition.parent );
 		}
 
-		for ( const node of this.markedTexts ) {
-			if ( !this.markedChildren.has( node.parent ) && this.domConverter.mapViewToDom( node.parent ) ) {
-				this._updateText( node, { inlineFillerPosition } );
-			}
-		}
-
 		for ( const element of this.markedAttributes ) {
 			this._updateAttrs( element );
 		}
@@ -212,6 +206,12 @@ export default class Renderer {
 			this._updateChildren( element, { inlineFillerPosition } );
 		}
 
+		for ( const node of this.markedTexts ) {
+			if ( !this.markedChildren.has( node.parent ) && this.domConverter.mapViewToDom( node.parent ) ) {
+				this._updateText( node, { inlineFillerPosition } );
+			}
+		}
+
 		// Check whether the inline filler is required and where it really is in the DOM.
 		// At this point in most cases it will be in the DOM, but there are exceptions.
 		// For example, if the inline filler was deep in the created DOM structure, it will not be created.
@@ -498,6 +498,8 @@ export default class Renderer {
 				nodesToUnbind.add( actualDomChildren[ i ] );
 				remove( actualDomChildren[ i ] );
 			} else { // 'equal'
+				// Inserted nodes are already up to date, so we mark to sync those which was not rerendered (#1125).
+				this._markDescendantTextToSync( domConverter.domToView( expectedDomChildren[ i ] ) );
 				i++;
 			}
 		}
@@ -532,6 +534,25 @@ export default class Renderer {
 	}
 
 	/**
+	 * Marks all text nodes in a tree starting from passed element to be synced.
+	 *
+	 * @private
+	 * @param {module:engine/view/element~Element} viewElement View element whose all 'text' children should
+	 * be marked to sync. If element is 'text' itself it will be marked too.
+	 */
+	_markDescendantTextToSync( viewElement ) {
+		if ( viewElement ) {
+			if ( viewElement.is( 'text' ) ) {
+				this.markedTexts.add( viewElement );
+			} else if ( viewElement.is( 'element' ) ) {
+				for ( const child of viewElement.getChildren() ) {
+					this._markDescendantTextToSync( child );
+				}
+			}
+		}
+	}
+
+	/**
 	 * Checks if selection needs to be updated and possibly updates it.
 	 *
 	 * @private