8
0
فهرست منبع

Fixed: Empty roots are shared between Paragraph plugin instances.

Oskar Wróbel 8 سال پیش
والد
کامیت
8e261dffd4
2فایلهای تغییر یافته به همراه63 افزوده شده و 44 حذف شده
  1. 62 43
      packages/ckeditor5-paragraph/src/paragraph.js
  2. 1 1
      packages/ckeditor5-paragraph/tests/paragraph.js

+ 62 - 43
packages/ckeditor5-paragraph/src/paragraph.js

@@ -39,6 +39,14 @@ export default class Paragraph extends Plugin {
 		const data = editor.data;
 		const editing = editor.editing;
 
+		/**
+		 * List of empty roots and batches that made them empty.
+		 *
+		 * @private
+		 * @type {Map<module:engine/model/rootelement~RootElement,module:engine/model/batch~Batch>}
+		 */
+		this._rootsToFix = new Map();
+
 		editor.commands.add( 'paragraph', new ParagraphCommand( editor ) );
 
 		// Schema.
@@ -84,14 +92,64 @@ export default class Paragraph extends Plugin {
 				return;
 			}
 
-			findEmptyRoots( doc, batch );
+			this._findEmptyRoots( batch );
 		} );
-		doc.on( 'changesDone', () => autoparagraphEmptyRoots( model ), { priority: 'lowest' } );
+		doc.on( 'changesDone', () => this._autoparagraphEmptyRoots(), { priority: 'lowest' } );
 		editor.on( 'dataReady', () => {
-			findEmptyRoots( doc, new Batch( 'transparent' ) );
-			autoparagraphEmptyRoots( model );
+			this._findEmptyRoots( new Batch( 'transparent' ) );
+			this._autoparagraphEmptyRoots();
 		}, { priority: 'lowest' } );
 	}
+
+	/**
+	 * Looks through all roots created in document and marks every empty root, saving which batch made it empty.
+	 *
+	 * @private
+	 * @param {module:engine/model/batch~Batch} batch Batch of current change.
+	 */
+	_findEmptyRoots( batch ) {
+		const doc = this.editor.model.document;
+
+		for ( const rootName of doc.getRootNames() ) {
+			const root = doc.getRoot( rootName );
+
+			if ( root.isEmpty ) {
+				if ( !this._rootsToFix.has( root ) ) {
+					this._rootsToFix.set( root, batch );
+				}
+			} else {
+				this._rootsToFix.delete( root );
+			}
+		}
+	}
+
+	/**
+	 * Fixes all empty roots.
+	 *
+	 * @private
+	 */
+	_autoparagraphEmptyRoots() {
+		const model = this.editor.model;
+
+		for ( const [ root, batch ] of this._rootsToFix ) {
+			// Only empty roots are in `#_rootsToFix`. Even if root got content during `changesDone` event (because of, for example
+			// other feature), this will fire `findEmptyRoots` and remove that root from `#_rootsToFix`. So we are guaranteed
+			// to have only empty roots here.
+			const query = { name: 'paragraph', inside: [ root ] };
+			const schema = model.schema;
+
+			// If paragraph element is allowed in the root, create paragraph element.
+			if ( schema.check( query ) ) {
+				model.enqueueChange( batch, writer => {
+					// Remove root from `rootsToFix` here, before executing batch, to prevent infinite loops.
+					this._rootsToFix.delete( root );
+
+					// Fix empty root.
+					writer.insertElement( 'paragraph', root );
+				} );
+			}
+		}
+	}
 }
 
 /**
@@ -259,42 +317,3 @@ function isParagraphable( node, context, schema, insideParagraphLikeElement ) {
 
 	return true;
 }
-
-// Looks through all roots created in document and marks every empty root, saving which batch made it empty.
-const rootsToFix = new Map();
-
-function findEmptyRoots( doc, batch ) {
-	for ( const rootName of doc.getRootNames() ) {
-		const root = doc.getRoot( rootName );
-
-		if ( root.isEmpty ) {
-			if ( !rootsToFix.has( root ) ) {
-				rootsToFix.set( root, batch );
-			}
-		} else {
-			rootsToFix.delete( root );
-		}
-	}
-}
-
-// Fixes all empty roots.
-function autoparagraphEmptyRoots( model ) {
-	for ( const [ root, batch ] of rootsToFix ) {
-		// Only empty roots are in `rootsToFix`. Even if root got content during `changesDone` event (because of, for example
-		// other feature), this will fire `findEmptyRoots` and remove that root from `rootsToFix`. So we are guaranteed
-		// to have only empty roots here.
-		const query = { name: 'paragraph', inside: [ root ] };
-		const schema = model.schema;
-
-		// If paragraph element is allowed in the root, create paragraph element.
-		if ( schema.check( query ) ) {
-			model.enqueueChange( batch, writer => {
-				// Remove root from `rootsToFix` here, before executing batch, to prevent infinite loops.
-				rootsToFix.delete( root );
-
-				// Fix empty root.
-				writer.insertElement( 'paragraph', root );
-			} );
-		}
-	}
-}

+ 1 - 1
packages/ckeditor5-paragraph/tests/paragraph.js

@@ -392,7 +392,7 @@ describe( 'Paragraph feature', () => {
 			editor.setData( '<p>Foobar</p>' );
 
 			// Since `setData` first removes all contents from editor and then sets content during same enqueue
-			// changes block, the line below checks whether fixing empty roots does not kick too early and does not
+			// change block, the line below checks whether fixing empty roots does not kick too early and does not
 			// fix root if it is not needed.
 			expect( editor.getData() ).to.equal( '<p>Foobar</p>' );