Browse Source

Improved Added methods for context handling in editor watchdog.

Maciej Bukowski 5 years ago
parent
commit
eff8186966

+ 50 - 32
packages/ckeditor5-watchdog/src/editorwatchdog.js

@@ -121,6 +121,49 @@ export default class EditorWatchdog extends Watchdog {
 	 * @param {Function} destructor
 	 */
 
+	setInitializationArgs( elementOrData, config ) {
+		this._elementOrData = elementOrData;
+
+		this._config = cloneDeepWith( config, value => {
+			// Leave DOM references.
+			return isElement( value ) ? value : undefined;
+		} );
+	}
+
+	updateContext( context ) {
+		this._config.context = context;
+	}
+
+	/**
+	 * Restarts the editor instance. This method is called whenever an editor error occurs. It fires the `restart` event and changes
+	 * the state to `initializing`.
+	 *
+	 * @public
+	 * @fires restart
+	 * @returns {Promise}
+	 */
+	async restart() {
+		this.state = 'initializing';
+
+		try {
+			await this._destroy();
+		} catch ( err ) {
+			console.error( 'An error happened during the editor destructing.', err );
+		}
+
+		if ( typeof this._elementOrData === 'string' ) {
+			await this.create( this._data, this._config );
+		} else {
+			const updatedConfig = Object.assign( {}, this._config, {
+				initialData: this._data
+			} );
+
+			await this.create( this._elementOrData, updatedConfig );
+		}
+
+		this.fire( 'restart' );
+	}
+
 	/**
 	 * Creates a watched editor instance using the creator passed to the {@link #setCreator `setCreator()`} method or
 	 * the {@link module:watchdog/watchdog~Watchdog.for `Watchdog.for()`} helper.
@@ -130,7 +173,7 @@ export default class EditorWatchdog extends Watchdog {
 	 *
 	 * @returns {Promise}
 	 */
-	async create( elementOrData, config ) {
+	async create( elementOrData = this._elementOrData, config = this._config ) {
 		if ( !this._creator ) {
 			/**
 			 * The watchdog's editor creator is not defined. Define it by using
@@ -182,12 +225,15 @@ export default class EditorWatchdog extends Watchdog {
 
 	async _destroy() {
 		this._stopErrorHandling();
+
 		// Save data if there is a remaining editor data change.
 		this._throttledSave.flush();
 
-		await this._destructor( this._editor );
+		const pendingDestruction = this._destructor( this._editor );
 
 		this._editor = null;
+
+		await pendingDestruction;
 	}
 
 	/**
@@ -234,36 +280,6 @@ export default class EditorWatchdog extends Watchdog {
 	}
 
 	/**
-	 * Restarts the editor instance. This method is called whenever an editor error occurs. It fires the `restart` event and changes
-	 * the state to `initializing`.
-	 *
-	 * @public
-	 * @fires restart
-	 * @returns {Promise}
-	 */
-	async restart() {
-		this.state = 'initializing';
-
-		try {
-			await this._destroy();
-		} catch ( err ) {
-			console.error( 'An error happened during the editor destructing.', err );
-		}
-
-		if ( typeof this._elementOrData === 'string' ) {
-			await this.create( this._data, this._config );
-		} else {
-			const updatedConfig = Object.assign( {}, this._config, {
-				initialData: this._data
-			} );
-
-			await this.create( this._elementOrData, updatedConfig );
-		}
-
-		this.fire( 'restart' );
-	}
-
-	/**
 	 * Traverses both structures to find out whether the error context is connected
 	 * with the current editor.
 	 *
@@ -271,6 +287,8 @@ export default class EditorWatchdog extends Watchdog {
 	 * @param {module:utils/ckeditorerror~CKEditorError} error
 	 */
 	_isErrorComingFromThisInstance( error ) {
+		// TODO - remove context from the path.
+
 		return areConnectedThroughProperties( this._editor, error.context );
 	}
 

+ 3 - 3
packages/ckeditor5-watchdog/src/watchdog.js

@@ -13,11 +13,11 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
 import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
 
 /**
- * A base watchdog class.
+ * An abstract watchdog class that handles most of the error handling process and the state of the underlying component.
  *
- * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and
- * how to use it.
+ * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and how to use it.
  *
+ * @private
  * @abstract
  */
 export default class Watchdog {

+ 24 - 33
packages/ckeditor5-watchdog/tests/editorwatchdog.js

@@ -144,11 +144,12 @@ describe( 'EditorWatchdog', () => {
 	describe( 'error handling', () => {
 		it( 'Watchdog should not restart editor during the initialization', () => {
 			const watchdog = new EditorWatchdog();
+			let editor;
 
-			watchdog.setCreator( el =>
-				ClassicTestEditor.create( el )
-					.then( () => Promise.reject( new Error( 'foo' ) ) )
-			);
+			watchdog.setCreator( async el => {
+				editor = await ClassicTestEditor.create( el );
+				await Promise.reject( new Error( 'foo' ) );
+			} );
 
 			return watchdog.create( element ).then(
 				() => { throw new Error( '`watchdog.create()` should throw an error.' ); },
@@ -156,29 +157,35 @@ describe( 'EditorWatchdog', () => {
 					expect( err ).to.be.instanceOf( Error );
 					expect( err.message ).to.equal( 'foo' );
 
-					return destroyEditorOrphans();
+					return editor.destroy();
 				}
 			);
 		} );
 
-		it( 'Watchdog should not restart editor during the destroy', () => {
+		it( 'Watchdog should not restart editor during the destroy', async () => {
 			const watchdog = new EditorWatchdog();
 
 			watchdog.setCreator( el => ClassicTestEditor.create( el ) );
 			watchdog.setDestructor( () => Promise.reject( new Error( 'foo' ) ) );
 
-			return Promise.resolve()
-				.then( () => watchdog.create( element ) )
-				.then( () => watchdog.destroy() )
-				.then(
-					() => { throw new Error( '`watchdog.create()` should throw an error.' ); },
-					err => {
-						expect( err ).to.be.instanceOf( Error );
-						expect( err.message ).to.equal( 'foo' );
+			await watchdog.create( element );
 
-						return destroyEditorOrphans();
-					}
-				);
+			let caughtError = false;
+			const editor = watchdog.editor;
+
+			try {
+				await watchdog.destroy();
+			} catch ( err ) {
+				caughtError = true;
+				expect( err ).to.be.instanceOf( Error );
+				expect( err.message ).to.equal( 'foo' );
+
+				await editor.destroy();
+			}
+
+			if ( !caughtError ) {
+				throw new Error( '`watchdog.create()` should throw an error.' );
+			}
 		} );
 
 		it( 'Watchdog should not hide intercepted errors', () => {
@@ -716,22 +723,6 @@ describe( 'EditorWatchdog', () => {
 				} );
 			} );
 		} );
-
-		// Searches for orphaned editors based on DOM.
-		//
-		// This is useful if in your tests you have no access to editor, instance because editor
-		// creation method doesn't complete in a graceful manner.
-		function destroyEditorOrphans() {
-			const promises = [];
-
-			for ( const editableOrphan of document.querySelectorAll( '.ck-editor__editable' ) ) {
-				if ( editableOrphan.ckeditorInstance ) {
-					promises.push( editableOrphan.ckeditorInstance.destroy() );
-				}
-			}
-
-			return Promise.all( promises );
-		}
 	} );
 
 	describe( 'async error handling', () => {