Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit ec89d8d

Browse files
authored
Merge pull request #132 from ckeditor/t/124
Feature: Added the observable `Editor#state` property. Closes #124.
2 parents 7dda00a + 4beced2 commit ec89d8d

File tree

8 files changed

+99
-116
lines changed

8 files changed

+99
-116
lines changed

src/editor/editor.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,24 @@ export default class Editor {
104104
*/
105105
this.t = this.locale.t;
106106

107+
/**
108+
* Indicates the editor life-cycle state.
109+
*
110+
* The editor is in one of the following states:
111+
*
112+
* * `initializing` - during the editor initialization (before {@link module:core/editor/editor~Editor.create `Editor.create()`)
113+
* finished its job,
114+
* * `ready` - after the promise returned by the {@link module:core/editor/editor~Editor.create `Editor.create()`}
115+
* method is resolved,
116+
* * `destroyed` - once the {@link #destroy `editor.destroy()`} method was called.
117+
*
118+
* @observable
119+
* @member {'initializing'|'ready'|'destroyed'} #state
120+
*/
121+
this.set( 'state', 'initializing' );
122+
this.once( 'ready', () => ( this.state = 'ready' ), { priority: 'high' } );
123+
this.once( 'destroy', () => ( this.state = 'destroyed' ), { priority: 'high' } );
124+
107125
/**
108126
* Defines whether this editor is in read-only mode.
109127
*
@@ -303,13 +321,18 @@ mix( Editor, ObservableMixin );
303321
* In fact, since the first moment when the editor instance is available to you is inside `then()`'s callback,
304322
* you cannot even add a listener to the `editor#ready` event.
305323
*
324+
* See also the {@link #state `editor.state`} property.
325+
*
306326
* @event ready
307327
*/
308328

309329
/**
310330
* Fired when this editor instance is destroyed. The editor at this point is not usable and this event should be used to
311331
* perform the clean-up in any plugin.
312332
*
333+
*
334+
* See also the {@link #state `editor.state`} property.
335+
*
313336
* @event destroy
314337
*/
315338

tests/_utils-tests/classictesteditor.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,20 @@ describe( 'ClassicTestEditor', () => {
129129
} );
130130
} );
131131

132+
it( 'sets proper states', () => {
133+
const editor = new ClassicTestEditor();
134+
135+
expect( editor.state ).to.equal( 'initializing' );
136+
137+
return ClassicTestEditor.create( editorElement ).then( editor => {
138+
expect( editor.state ).to.equal( 'ready' );
139+
140+
return editor.destroy().then( () => {
141+
expect( editor.state ).to.equal( 'destroyed' );
142+
} );
143+
} );
144+
} );
145+
132146
it( 'inserts editor UI next to editor element', () => {
133147
return ClassicTestEditor.create( editorElement )
134148
.then( editor => {

tests/_utils-tests/modeltesteditor.js

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import Editor from '../../src/editor/editor';
77
import EditingController from '@ckeditor/ckeditor5-engine/src/controller/editingcontroller';
88
import ModelTestEditor from '../../tests/_utils/modeltesteditor';
99

10-
import Plugin from '../../src/plugin';
1110
import HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';
1211
import DataApiMixin from '../../src/editor/utils/dataapimixin';
1312
import RootElement from '@ckeditor/ckeditor5-engine/src/model/rootelement';
@@ -49,41 +48,6 @@ describe( 'ModelTestEditor', () => {
4948
} );
5049
} );
5150

52-
describe( 'create', () => {
53-
it( 'creates an instance of editor', () => {
54-
return ModelTestEditor.create( { foo: 1 } )
55-
.then( editor => {
56-
expect( editor ).to.be.instanceof( ModelTestEditor );
57-
58-
expect( editor.config.get( 'foo' ) ).to.equal( 1 );
59-
} );
60-
} );
61-
62-
it( 'fires all events in the right order', () => {
63-
const fired = [];
64-
65-
function spy( evt ) {
66-
fired.push( evt.name );
67-
}
68-
69-
class EventWatcher extends Plugin {
70-
init() {
71-
this.editor.on( 'pluginsReady', spy );
72-
this.editor.on( 'dataReady', spy );
73-
this.editor.on( 'ready', spy );
74-
}
75-
}
76-
77-
return ModelTestEditor
78-
.create( {
79-
plugins: [ EventWatcher ]
80-
} )
81-
.then( () => {
82-
expect( fired ).to.deep.equal( [ 'pluginsReady', 'dataReady', 'ready' ] );
83-
} );
84-
} );
85-
} );
86-
8751
describe( 'setData', () => {
8852
let editor;
8953

tests/_utils-tests/virtualtesteditor.js

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import Editor from '../../src/editor/editor';
77
import VirtualTestEditor from '../../tests/_utils/virtualtesteditor';
88

9-
import Plugin from '../../src/plugin';
109
import HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';
1110
import DataApiMixin from '../../src/editor/utils/dataapimixin';
1211
import RootElement from '@ckeditor/ckeditor5-engine/src/model/rootelement';
@@ -35,39 +34,4 @@ describe( 'VirtualTestEditor', () => {
3534
expect( testUtils.isMixed( VirtualTestEditor, DataApiMixin ) ).to.true;
3635
} );
3736
} );
38-
39-
describe( 'create', () => {
40-
it( 'creates an instance of editor', () => {
41-
return VirtualTestEditor.create( { foo: 1 } )
42-
.then( editor => {
43-
expect( editor ).to.be.instanceof( VirtualTestEditor );
44-
45-
expect( editor.config.get( 'foo' ) ).to.equal( 1 );
46-
} );
47-
} );
48-
49-
it( 'fires all events in the right order', () => {
50-
const fired = [];
51-
52-
function spy( evt ) {
53-
fired.push( evt.name );
54-
}
55-
56-
class EventWatcher extends Plugin {
57-
init() {
58-
this.editor.on( 'pluginsReady', spy );
59-
this.editor.on( 'dataReady', spy );
60-
this.editor.on( 'ready', spy );
61-
}
62-
}
63-
64-
return VirtualTestEditor
65-
.create( {
66-
plugins: [ EventWatcher ]
67-
} )
68-
.then( () => {
69-
expect( fired ).to.deep.equal( [ 'pluginsReady', 'dataReady', 'ready' ] );
70-
} );
71-
} );
72-
} );
7337
} );

tests/_utils/classictesteditor.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export default class ClassicTestEditor extends Editor {
7575
.then( () => editor.data.init( getDataFromElement( element ) ) )
7676
.then( () => {
7777
editor.fire( 'dataReady' );
78+
editor.state = 'ready';
7879
editor.fire( 'ready' );
7980
} )
8081
.then( () => editor )

tests/_utils/modeltesteditor.js

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,28 +29,6 @@ export default class ModelTestEditor extends Editor {
2929
// Create the ("main") root element of the model tree.
3030
this.model.document.createRoot();
3131
}
32-
33-
/**
34-
* Creates a virtual, element-less editor instance.
35-
*
36-
* @param {Object} config See {@link core.editor.Editor}'s param.
37-
* @returns {Promise} Promise resolved once editor is ready.
38-
* @returns {core.editor.VirtualTestEditor} return.editor The editor instance.
39-
*/
40-
static create( config ) {
41-
return new Promise( resolve => {
42-
const editor = new this( config );
43-
44-
resolve(
45-
editor.initPlugins()
46-
.then( () => {
47-
editor.fire( 'dataReady' );
48-
editor.fire( 'ready' );
49-
} )
50-
.then( () => editor )
51-
);
52-
} );
53-
}
5432
}
5533

5634
mix( ModelTestEditor, DataApiMixin );

tests/_utils/virtualtesteditor.js

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,6 @@ export default class VirtualTestEditor extends Editor {
2626
// Create the ("main") root element of the model tree.
2727
this.model.document.createRoot();
2828
}
29-
30-
/**
31-
* Creates a virtual, element-less editor instance.
32-
*
33-
* @param {Object} config See {@link core.editor.Editor}'s param.
34-
* @returns {Promise} Promise resolved once editor is ready.
35-
* @returns {core.editor.VirtualTestEditor} return.editor The editor instance.
36-
*/
37-
static create( config ) {
38-
return new Promise( resolve => {
39-
const editor = new this( config );
40-
41-
resolve(
42-
editor.initPlugins()
43-
.then( () => {
44-
editor.fire( 'dataReady' );
45-
editor.fire( 'ready' );
46-
} )
47-
.then( () => editor )
48-
);
49-
} );
50-
}
5129
}
5230

5331
mix( VirtualTestEditor, DataApiMixin );

tests/editor/editor.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,67 @@ describe( 'Editor', () => {
181181
} );
182182
} );
183183

184+
describe( 'state', () => {
185+
it( 'is `initializing` initially', () => {
186+
const editor = new Editor();
187+
188+
expect( editor.state ).to.equal( 'initializing' );
189+
} );
190+
191+
it( 'is `ready` after initialization chain', () => {
192+
return Editor.create().then( editor => {
193+
expect( editor.state ).to.equal( 'ready' );
194+
195+
return editor.destroy();
196+
} );
197+
} );
198+
199+
it( 'is `destroyed` after editor destroy', () => {
200+
const editor = new Editor();
201+
202+
return editor.destroy().then( () => {
203+
expect( editor.state ).to.equal( 'destroyed' );
204+
} );
205+
} );
206+
207+
it( 'is observable', () => {
208+
const editor = new Editor();
209+
const spy = sinon.spy();
210+
211+
editor.on( 'change:state', spy );
212+
213+
editor.state = 'ready';
214+
215+
sinon.assert.calledOnce( spy );
216+
} );
217+
218+
it( 'reacts on #ready event', done => {
219+
const editor = new Editor();
220+
221+
expect( editor.state ).to.equal( 'initializing' );
222+
223+
editor.on( 'ready', () => {
224+
expect( editor.state ).to.equal( 'ready' );
225+
done();
226+
} );
227+
228+
editor.fire( 'ready' );
229+
} );
230+
231+
it( 'reacts on #destroy event', done => {
232+
const editor = new Editor();
233+
234+
expect( editor.state ).to.equal( 'initializing' );
235+
236+
editor.on( 'destroy', () => {
237+
expect( editor.state ).to.equal( 'destroyed' );
238+
done();
239+
} );
240+
241+
editor.fire( 'destroy' );
242+
} );
243+
} );
244+
184245
describe( 'isReadOnly', () => {
185246
it( 'is false initially', () => {
186247
const editor = new Editor();

0 commit comments

Comments
 (0)