8
0
Просмотр исходного кода

Refactor DowncastDispatcher.convertChanges().

Maciej Gołaszewski 5 лет назад
Родитель
Сommit
ac568421d3
1 измененных файлов с 42 добавлено и 46 удалено
  1. 42 46
      packages/ckeditor5-engine/src/conversion/downcastdispatcher.js

+ 42 - 46
packages/ckeditor5-engine/src/conversion/downcastdispatcher.js

@@ -133,54 +133,12 @@ export default class DowncastDispatcher {
 	 * @param {module:engine/view/downcastwriter~DowncastWriter} writer The view writer that should be used to modify the view document.
 	 */
 	convertChanges( differ, markers, writer ) {
-		const changes1 = differ.getChanges();
-
-		const mapRefreshedBy = new Map();
-
-		const found = [ ...changes1 ]
-			.filter( ( { type } ) => type === 'attribute' || type === 'insert' || type === 'remove' )
-			.map( entry => {
-				const { range, position, type } = entry;
-				const element = range && range.start.nodeAfter || position && position.parent;
-
-				let eventName;
-
-				if ( type === 'attribute' ) {
-					// TODO: enhance event name retrieval.
-					eventName = `attribute:${ entry.attributeKey }:${ element && element.name }`;
-				} else {
-					eventName = `${ type }:${ entry.name }`;
-				}
-
-				if ( this._refreshEventMap.has( eventName ) ) {
-					const expectedElement = this._refreshEventMap.get( eventName );
-
-					const handledByParent = element.is( 'element', expectedElement ) ? element : element.findAncestor( expectedElement );
-
-					if ( handledByParent ) {
-						mapRefreshedBy.set( element, handledByParent );
-					}
-
-					return handledByParent;
-				}
-			} )
-			.filter( element => !!element );
-
-		const elementsToRefresh = new Set( found );
-
-		[ ...elementsToRefresh.values() ].forEach( element => differ.refreshItem( element ) );
-
 		// Before the view is updated, remove markers which have changed.
 		for ( const change of differ.getMarkersToRemove() ) {
 			this.convertMarkerRemove( change.name, change.range, writer );
 		}
 
-		const changes = differ.getChanges().filter( entry => {
-			const { range, position } = entry;
-			const element = range && range.start.nodeAfter || position && position.parent;
-
-			return !mapRefreshedBy.has( element );
-		} );
+		const changes = this._getChangesAfterAutomaticRefreshing( differ );
 
 		// Convert changes that happened on model tree.
 		for ( const entry of changes ) {
@@ -342,9 +300,7 @@ export default class DowncastDispatcher {
 		// Create a list of things that can be consumed, consisting of nodes and their attributes.
 		this.conversionApi.consumable = this._createInsertConsumable( range );
 
-		const values = [ ...range ];
-
-		for ( const value of values ) {
+		for ( const value of range ) {
 			const item = value.item;
 			const itemRange = Range._createFromPositionAndShift( value.previousPosition, value.length );
 			const data = {
@@ -357,6 +313,7 @@ export default class DowncastDispatcher {
 			// Main element refresh - kinda ugly as we have all items in the range.
 			// TODO: Maybe, an inner range would be better (check children, etc).
 			const mainEvent = 'insert:' + name;
+
 			if ( expectedEventName === mainEvent ) {
 				// Cache current view element of a converted element, might be undefined if first insert.
 				const currentView = this.conversionApi.mapper.toViewElement( data.item );
@@ -667,6 +624,39 @@ export default class DowncastDispatcher {
 		delete this.conversionApi.consumable;
 	}
 
+	_getChangesAfterAutomaticRefreshing( differ ) {
+		const elementsToRefresh = this._getElementsForAutomaticRefresh( differ );
+
+		for ( const element of elementsToRefresh.values() ) {
+			differ.refreshItem( element );
+		}
+
+		return differ.getChanges().filter( entry => !elementsToRefresh.has( getElementFromChange( entry ) ) );
+	}
+
+	_getElementsForAutomaticRefresh( differ ) {
+		const found = differ.getChanges()
+			.filter( ( { type } ) => type === 'attribute' || type === 'insert' || type === 'remove' )
+			.map( entry => {
+				const element = getElementFromChange( entry );
+
+				let eventName;
+
+				if ( entry.type === 'attribute' ) {
+					eventName = `attribute:${ entry.attributeKey }:${ element && element.name }`;
+				} else {
+					eventName = `${ entry.type }:${ entry.name }`;
+				}
+
+				if ( this._refreshEventMap.has( eventName ) ) {
+					return element;
+				}
+			} )
+			.filter( element => !!element );
+
+		return new Set( found );
+	}
+
 	/**
 	 * Fired for inserted nodes.
 	 *
@@ -820,6 +810,12 @@ function getEventName( type, data ) {
 	return `${ type }:${ name }`;
 }
 
+function getElementFromChange( entry ) {
+	const { range, position, type } = entry;
+
+	return type === 'attribute' ? range.start.nodeAfter : position.parent;
+}
+
 /**
  * Conversion interface that is registered for given {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}
  * and is passed as one of parameters when {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher dispatcher}