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

Changed the way of marking context as created by the editor.

Oskar Wróbel 6 лет назад
Родитель
Сommit
b4f0eef47a

+ 32 - 3
packages/ckeditor5-core/src/context.js

@@ -59,6 +59,15 @@ export default class Context {
 		 */
 		this.t = this.locale.t;
 
+		/**
+		 * When the context is created by an editor then the editor instance is
+		 * stored as an owner of this context.
+		 *
+		 * @readonly
+		 * @type {Boolean}
+		 */
+		this.isCreatedByEditor = false;
+
 		/**
 		 * List of editors to which this context instance is injected.
 		 *
@@ -69,16 +78,36 @@ export default class Context {
 	}
 
 	/**
-	 * Adds a reference to the editor to which context is injected.
+	 * Adds a reference to the editor which is used with this context.
+	 *
+	 * When the context is created by the editor it is additionally
+	 * marked as a {@link ~Context#isCreatedByEditor} what is used
+	 * in the destroy chain.
 	 *
 	 * @param {module:core/editor/editor~Editor} editor
+	 * @param {Boolean} isContextOwner
 	 */
-	addEditor( editor ) {
+	addEditor( editor, isContextOwner ) {
+		if ( this.isCreatedByEditor ) {
+			/**
+			 * Cannot add multiple editors to the context which is created by the editor.
+			 *
+			 * @error context-addEditor-to-private-context
+			 */
+			throw new CKEditorError(
+				'context-addEditor-to-private-context: Cannot add multiple editors to the context which is created by the editor.'
+			);
+		}
+
 		this._editors.add( editor );
+
+		if ( isContextOwner ) {
+			this.isCreatedByEditor = true;
+		}
 	}
 
 	/**
-	 * Removes a reference to the editor to which context was injected.
+	 * Removes a reference to the editor which was used with this context.
 	 *
 	 * @param {module:core/editor/editor~Editor} editor
 	 */

+ 9 - 10
packages/ckeditor5-core/src/editor/editor.js

@@ -52,19 +52,14 @@ export default class Editor {
 	 */
 	constructor( config = {} ) {
 		/**
+		 * The editor context.
+		 * When it is not provided through the configuration then the editor creates it.
+		 *
 		 * @readonly
 		 * @type {module:core/context~Context}
 		 */
 		this.context = config.context || new Context( { language: config.language } );
-		this.context.addEditor( this );
-
-		/**
-		 * `true` when context is created by this editor or `false` when context is injected to the editor.
-		 *
-		 * @private
-		 * @type {Boolean}
-		 */
-		this._isContextHost = !config.context;
+		this.context.addEditor( this, !config.context );
 
 		const availablePlugins = this.constructor.builtinPlugins;
 
@@ -257,9 +252,13 @@ export default class Editor {
 
 		return readyPromise
 			.then( () => {
+				// Remove the editor from the context to avoid destroying it
+				// one more time when context will be destroyed.
 				this.context.removeEditor( this );
 
-				if ( this._isContextHost ) {
+				// When the editor was an owner of the context then
+				// the context should be destroyed along with the editor.
+				if ( this.context.isCreatedByEditor ) {
 					return this.context.destroy();
 				}
 			} ).then( () => {

+ 11 - 0
packages/ckeditor5-core/tests/editor/editor.js

@@ -186,6 +186,7 @@ describe( 'Editor', () => {
 			const editor = new TestEditor();
 
 			expect( editor.context ).to.be.an.instanceof( Context );
+			expect( editor.context.isCreatedByEditor ).to.true;
 		} );
 
 		it( 'should use context given through configuration when is defined', async () => {
@@ -193,6 +194,16 @@ describe( 'Editor', () => {
 			const editor = new TestEditor( { context } );
 
 			expect( editor.context ).to.equal( context );
+			expect( editor.context.isCreatedByEditor ).to.false;
+		} );
+
+		it( 'should throw when try to use context created by one editor with the other editor', () => {
+			const editor = new TestEditor();
+
+			expectToThrowCKEditorError( () => {
+				// eslint-disable-next-line no-new
+				new TestEditor( { context: editor.context } );
+			}, /^context-addEditor-to-private-context/ );
 		} );
 
 		it( 'should destroy context created by the editor on editor destroy', async () => {