瀏覽代碼

Added editor events marking different stages of its initialisation.

Piotrek Koszuliński 9 年之前
父節點
當前提交
3f93ac451b

+ 36 - 3
packages/ckeditor5-core/src/editor/editor.js

@@ -109,7 +109,10 @@ export default class Editor {
 		const config = this.config;
 
 		return loadPlugins()
-			.then( initPlugins );
+			.then( initPlugins )
+			.then( () => {
+				this.fire( 'pluginsReady' );
+			} );
 
 		function loadPlugins() {
 			return that.plugins.load( config.get( 'plugins' ) || [] );
@@ -163,9 +166,9 @@ export default class Editor {
 	/**
 	 * Creates a basic editor instance.
 	 *
-	 * @param {Object} config See {@link module:core/editor/editor~StandardEditor}'s param.
+	 * @param {Object} config See {@link module:core/editor/editor~Editor}'s param.
 	 * @returns {Promise} Promise resolved once editor is ready.
-	 * @returns {module:core/editor/editor~StandardEditor} return.editor The editor instance.
+	 * @returns {module:core/editor/editor~Editor} return.editor The editor instance.
 	 */
 	static create( config ) {
 		return new Promise( ( resolve ) => {
@@ -173,6 +176,10 @@ export default class Editor {
 
 			resolve(
 				editor.initPlugins()
+					.then( () => {
+						editor.fire( 'dataReady' );
+						editor.fire( 'ready' );
+					} )
 					.then( () => editor )
 			);
 		} );
@@ -182,6 +189,32 @@ export default class Editor {
 mix( Editor, EmitterMixin );
 
 /**
+ * Fired after {@link core.editor.Editor#initPlugins plugins are initialized}.
+ *
+ * @event core.editor.Editor#pluginsReady
+ */
+
+/**
+ * Fired when the editor UI is ready. This event won't be fired if the editor has no UI.
+ *
+ * @event core.editor.Editor#uiReady
+ */
+
+/**
+ * Fired when the data loaded to the editor is ready. If a specific editor doesn't load
+ * any data initially, this event will be fired right before {@link #ready}.
+ *
+ * @event core.editor.Editor#dataReady
+ */
+
+/**
+ * Fired when {@link #pluginsReady plugins}, {@link #uiReady UI} and {@link #dataReady data} and all additional
+ * editor components are ready.
+ *
+ * @event core.editor.Editor#ready
+ */
+
+/**
  * Fired when this editor instance is destroyed. The editor at this point is not usable and this event should be used to
  * perform the clean-up in any plugin.
  *

+ 4 - 0
packages/ckeditor5-core/src/editor/standardeditor.js

@@ -113,6 +113,10 @@ export default class StandardEditor extends Editor {
 
 			resolve(
 				editor.initPlugins()
+					.then( () => {
+						editor.fire( 'dataReady' );
+						editor.fire( 'ready' );
+					} )
 					.then( () => editor )
 			);
 		} );

+ 24 - 0
packages/ckeditor5-core/tests/_utils-tests/classictesteditor.js

@@ -80,6 +80,30 @@ describe( 'ClassicTestEditor', () => {
 					expect( getData( editor.document, { withoutSelection: true } ) ).to.equal( 'foo' );
 				} );
 		} );
+
+		it( 'fires all events in the right order', () => {
+			const fired = [];
+
+			function spy( evt ) {
+				fired.push( evt.name );
+			}
+
+			class EventWatcher extends Plugin {
+				init() {
+					this.editor.on( 'pluginsReady', spy );
+					this.editor.on( 'uiReady', spy );
+					this.editor.on( 'dataReady', spy );
+					this.editor.on( 'ready', spy );
+				}
+			}
+
+			return ClassicTestEditor.create( editorElement, {
+					plugins: [ EventWatcher ]
+				} )
+				.then( () => {
+					expect( fired ).to.deep.equal( [ 'pluginsReady', 'uiReady', 'dataReady', 'ready' ] );
+				} );
+		} );
 	} );
 
 	describe( 'destroy', () => {

+ 26 - 0
packages/ckeditor5-core/tests/_utils-tests/modeltesteditor.js

@@ -5,7 +5,10 @@
 
 import Editor from 'ckeditor5/core/editor/editor.js';
 import ModelTestEditor from 'tests/core/_utils/modeltesteditor.js';
+
+import Plugin from 'ckeditor5/core/plugin.js';
 import HtmlDataProcessor from 'ckeditor5/engine/dataprocessor/htmldataprocessor.js';
+
 import { getData, setData } from 'ckeditor5/engine/dev-utils/model.js';
 
 import testUtils from 'tests/core/_utils/utils.js';
@@ -39,6 +42,29 @@ describe( 'ModelTestEditor', () => {
 					expect( editor.config.get( 'foo' ) ).to.equal( 1 );
 				} );
 		} );
+
+		it( 'fires all events in the right order', () => {
+			const fired = [];
+
+			function spy( evt ) {
+				fired.push( evt.name );
+			}
+
+			class EventWatcher extends Plugin {
+				init() {
+					this.editor.on( 'pluginsReady', spy );
+					this.editor.on( 'dataReady', spy );
+					this.editor.on( 'ready', spy );
+				}
+			}
+
+			return ModelTestEditor.create( {
+					plugins: [ EventWatcher ]
+				} )
+				.then( () => {
+					expect( fired ).to.deep.equal( [ 'pluginsReady', 'dataReady', 'ready' ] );
+				} );
+		} );
 	} );
 
 	describe( 'setData', () => {

+ 25 - 0
packages/ckeditor5-core/tests/_utils-tests/virtualtesteditor.js

@@ -5,6 +5,8 @@
 
 import StandardEditor from 'ckeditor5/core/editor/standardeditor.js';
 import VirtualTestEditor from 'tests/core/_utils/virtualtesteditor.js';
+
+import Plugin from 'ckeditor5/core/plugin.js';
 import HtmlDataProcessor from 'ckeditor5/engine/dataprocessor/htmldataprocessor.js';
 
 import testUtils from 'tests/core/_utils/utils.js';
@@ -39,5 +41,28 @@ describe( 'VirtualTestEditor', () => {
 					expect( editor.config.get( 'foo' ) ).to.equal( 1 );
 				} );
 		} );
+
+		it( 'fires all events in the right order', () => {
+			const fired = [];
+
+			function spy( evt ) {
+				fired.push( evt.name );
+			}
+
+			class EventWatcher extends Plugin {
+				init() {
+					this.editor.on( 'pluginsReady', spy );
+					this.editor.on( 'dataReady', spy );
+					this.editor.on( 'ready', spy );
+				}
+			}
+
+			return VirtualTestEditor.create( {
+					plugins: [ EventWatcher ]
+				} )
+				.then( () => {
+					expect( fired ).to.deep.equal( [ 'pluginsReady', 'dataReady', 'ready' ] );
+				} );
+		} );
 	} );
 } );

+ 5 - 0
packages/ckeditor5-core/tests/_utils/classictesteditor.js

@@ -46,7 +46,12 @@ export default class ClassicTestEditor extends StandardEditor {
 			resolve(
 				editor.initPlugins()
 					.then( () => editor.ui.init() )
+					.then( () => editor.fire( 'uiReady' ) )
 					.then( () => editor.loadDataFromEditorElement() )
+					.then( () => {
+						editor.fire( 'dataReady' );
+						editor.fire( 'ready' );
+					} )
 					.then( () => editor )
 			);
 		} );

+ 4 - 0
packages/ckeditor5-core/tests/_utils/modeltesteditor.js

@@ -52,6 +52,10 @@ export default class ModelTestEditor extends Editor {
 
 			resolve(
 				editor.initPlugins()
+					.then( () => {
+						editor.fire( 'dataReady' );
+						editor.fire( 'ready' );
+					} )
 					.then( () => editor )
 			);
 		} );

+ 4 - 0
packages/ckeditor5-core/tests/_utils/virtualtesteditor.js

@@ -38,6 +38,10 @@ export default class VirtualTestEditor extends StandardEditor {
 
 			resolve(
 				editor.initPlugins()
+					.then( () => {
+						editor.fire( 'dataReady' );
+						editor.fire( 'ready' );
+					} )
 					.then( () => editor )
 			);
 		} );

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

@@ -84,6 +84,29 @@ describe( 'Editor', () => {
 					expect( editor.plugins.get( PluginA ) ).to.be.an.instanceof( Plugin );
 				} );
 		} );
+
+		it( 'fires all events in the right order', () => {
+			const fired = [];
+
+			function spy( evt ) {
+				fired.push( evt.name );
+			}
+
+			class EventWatcher extends Plugin {
+				init() {
+					this.editor.on( 'pluginsReady', spy );
+					this.editor.on( 'dataReady', spy );
+					this.editor.on( 'ready', spy );
+				}
+			}
+
+			return Editor.create( {
+					plugins: [ EventWatcher ]
+				} )
+				.then( () => {
+					expect( fired ).to.deep.equal( [ 'pluginsReady', 'dataReady', 'ready' ] );
+				} );
+		} );
 	} );
 
 	describe( 'initPlugins', () => {

+ 23 - 0
packages/ckeditor5-core/tests/editor/standardeditor.js

@@ -55,6 +55,29 @@ describe( 'StandardEditor', () => {
 					expect( editor.plugins.get( PluginFoo ) ).to.be.instanceof( PluginFoo );
 				} );
 		} );
+
+		it( 'fires all events in the right order', () => {
+			const fired = [];
+
+			function spy( evt ) {
+				fired.push( evt.name );
+			}
+
+			class EventWatcher extends Plugin {
+				init() {
+					this.editor.on( 'pluginsReady', spy );
+					this.editor.on( 'dataReady', spy );
+					this.editor.on( 'ready', spy );
+				}
+			}
+
+			return StandardEditor.create( editorElement, {
+					plugins: [ EventWatcher ]
+				} )
+				.then( () => {
+					expect( fired ).to.deep.equal( [ 'pluginsReady', 'dataReady', 'ready' ] );
+				} );
+		} );
 	} );
 
 	describe( 'setData', () => {