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

Improved the performance of the view post-fixer by keeping track of widgets that have the type around UI injected.

Aleksander Nowodzinski 5 лет назад
Родитель
Сommit
eb42ca5461
1 измененных файлов с 40 добавлено и 12 удалено
  1. 40 12
      packages/ckeditor5-widget/src/widgettypearound/widgettypearound.js

+ 40 - 12
packages/ckeditor5-widget/src/widgettypearound/widgettypearound.js

@@ -57,6 +57,32 @@ export default class WidgetTypeAround extends Plugin {
 		return 'WidgetTypeAround';
 	}
 
+	/**
+	 * @inheritDoc
+	 */
+	constructor( editor ) {
+		super( editor );
+
+		/**
+		 * A set containing all widgets in all editor roots that have the type around UI injected in
+		 * {@link #_enableTypeAroundUIInjection}.
+		 *
+		 * Keeping track of them saves time, for instance, when updating their CSS classes.
+		 *
+		 * @private
+		 * @readonly
+		 * @member {Set} #_widgetsWithTypeAroundUI
+		 */
+		this._widgetsWithTypeAroundUI = new Set();
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	destroy() {
+		this._widgetsWithTypeAroundUI.clear();
+	}
+
 	/**
 	 * @inheritDoc
 	 */
@@ -124,6 +150,11 @@ export default class WidgetTypeAround extends Plugin {
 			// Filter out non-widgets and inline widgets.
 			if ( isTypeAroundWidget( viewElement, data.item, schema ) ) {
 				injectUIIntoWidget( conversionApi.writer, buttonTitles, viewElement );
+
+				// Keep track of widgets that have the type around UI injected.
+				// In the #_enableDetectionOfTypeAroundWidgets() we will iterate only over these
+				// widgets instead of all children of the root. This should improve the performance.
+				this._widgetsWithTypeAroundUI.add( viewElement );
 			}
 		}, { priority: 'low' } );
 	}
@@ -137,7 +168,6 @@ export default class WidgetTypeAround extends Plugin {
 	 */
 	_enableDetectionOfTypeAroundWidgets() {
 		const editor = this.editor;
-		const schema = editor.model.schema;
 		const editingView = editor.editing.view;
 
 		function positionToWidgetCssClass( position ) {
@@ -145,16 +175,13 @@ export default class WidgetTypeAround extends Plugin {
 		}
 
 		editingView.document.registerPostFixer( writer => {
-			// Find all view elements in the editing root.
-			[ ...editingView.createRangeIn( editingView.document.getRoot() ) ]
-				// ...then filter only the widgets that may need the type around feature.
-				.filter( ( { item: widgetViewElement } ) => {
-					const modelElement = editor.editing.mapper.toModelElement( widgetViewElement );
-
-					return isTypeAroundWidget( widgetViewElement, modelElement, schema );
-				} )
-				// ...and update widgets' classes depending on possible positions for paragraph insertion.
-				.forEach( ( { item: widgetViewElement } ) => {
+			for ( const widgetViewElement of this._widgetsWithTypeAroundUI ) {
+				// If the widget is no longer attached to the root (for instance, because it was removed),
+				// there is no need to update its classes and we can safely forget about it.
+				if ( !widgetViewElement.isAttached() ) {
+					this._widgetsWithTypeAroundUI.delete( widgetViewElement );
+				} else {
+					// Update widgets' classes depending on possible positions for paragraph insertion.
 					const positions = getWidgetTypeAroundPositions( widgetViewElement );
 
 					// Remove all classes. In theory we could remove only these that will not be added a few lines later,
@@ -163,7 +190,8 @@ export default class WidgetTypeAround extends Plugin {
 
 					// Set CSS classes related to possible positions. They are used so the UI knows which buttons to display.
 					writer.addClass( positions.map( positionToWidgetCssClass ), widgetViewElement );
-				} );
+				}
+			}
 		} );
 	}