Skip to content

Commit df4410a

Browse files
authored
Merge pull request #156 from ckeditor/i/153-performance
Fix: The editor should now slow down with lots of content when using the integration. Closes #153.
2 parents 20dee60 + ad5afb4 commit df4410a

File tree

6 files changed

+42
-41
lines changed

6 files changed

+42
-41
lines changed

Diff for: dist/ckeditor.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: dist/ckeditor.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: src/ckeditor.js

+17-16
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export default {
4343
return {
4444
// Don't define it in #props because it produces a warning.
4545
// https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow
46-
instance: null,
46+
$_instance: null,
4747

4848
$_lastEditorData: {
4949
type: String,
@@ -63,8 +63,8 @@ export default {
6363

6464
this.editor.create( this.$el, editorConfig )
6565
.then( editor => {
66-
// Save the reference to the instance for further use.
67-
this.instance = editor;
66+
// Save the reference to the $_instance for further use.
67+
this.$_instance = editor;
6868

6969
// Set initial disabled state.
7070
editor.isReadOnly = this.disabled;
@@ -80,19 +80,19 @@ export default {
8080
},
8181

8282
beforeDestroy() {
83-
if ( this.instance ) {
84-
this.instance.destroy();
85-
this.instance = null;
83+
if ( this.$_instance ) {
84+
this.$_instance.destroy();
85+
this.$_instance = null;
8686
}
8787

8888
// Note: By the time the editor is destroyed (promise resolved, editor#destroy fired)
8989
// the Vue component will not be able to emit any longer. So emitting #destroy a bit earlier.
90-
this.$emit( 'destroy', this.instance );
90+
this.$emit( 'destroy', this.$_instance );
9191
},
9292

9393
watch: {
9494
value( newValue, oldValue ) {
95-
// Synchronize changes of instance#value. There are two sources of changes:
95+
// Synchronize changes of #value. There are two sources of changes:
9696
//
9797
// External value change ------\
9898
// -----> +-----------+
@@ -102,32 +102,33 @@ export default {
102102
// (typing, commands, collaboration)
103103
//
104104
// Case 1: If the change was external (via props), the editor data must be synced with
105-
// the component using instance#setData() and it is OK to destroy the selection.
105+
// the component using $_instance#setData() and it is OK to destroy the selection.
106106
//
107107
// Case 2: If the change is the result of internal data change, the #value is the same as
108-
// instance#$_lastEditorData, which has been cached on instance#change:data. If we called
109-
// instance#setData() at this point, that would demolish the selection.
108+
// this.$_lastEditorData, which has been cached on #change:data. If we called
109+
// $_instance#setData() at this point, that would demolish the selection.
110110
//
111-
// To limit the number of instance#setData() which is time-consuming when there is a
111+
// To limit the number of $_instance#setData() which is time-consuming when there is a
112112
// lot of data we make sure:
113113
// * the new value is at least different than the old value (Case 1.)
114114
// * the new value is different than the last internal instance state (Case 2.)
115115
//
116116
// See: https://github.com/ckeditor/ckeditor5-vue/issues/42.
117117
if ( newValue !== oldValue && newValue !== this.$_lastEditorData ) {
118-
this.instance.setData( newValue );
118+
this.$_instance.setData( newValue );
119119
}
120120
},
121121

122122
// Synchronize changes of #disabled.
123123
disabled( val ) {
124-
this.instance.isReadOnly = val;
124+
this.$_instance.isReadOnly = val;
125125
}
126126
},
127127

128128
methods: {
129129
$_setUpEditorEvents() {
130-
const editor = this.instance;
130+
const editor = this.$_instance;
131+
131132
// Use the leading edge so the first event in the series is emitted immediately.
132133
// Failing to do so leads to race conditions, for instance, when the component value
133134
// is set twice in a time span shorter than the debounce time.
@@ -142,7 +143,7 @@ export default {
142143
this.$emit( 'input', data, evt, editor );
143144
}, INPUT_EVENT_DEBOUNCE_WAIT, { leading: true } );
144145

145-
// Debounce emitting the #input event. When data is huge, instance#getData()
146+
// Debounce emitting the #input event. When data is huge, $_instance#getData()
146147
// takes a lot of time to execute on every single key press and ruins the UX.
147148
//
148149
// See: https://github.com/ckeditor/ckeditor5-vue/issues/42

Diff for: tests/ckeditor.js

+20-20
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ describe( 'CKEditor Component', () => {
5050

5151
wrapper.destroy();
5252
sinon.assert.calledOnce( stub );
53-
expect( vm.instance ).to.be.null;
53+
expect( vm.$_instance ).to.be.null;
5454
} );
5555

5656
it( 'should pass the editor promise rejection error to console#error()', async () => {
@@ -81,7 +81,7 @@ describe( 'CKEditor Component', () => {
8181
await Vue.nextTick();
8282

8383
expect( vm.editor ).to.equal( MockEditor );
84-
expect( vm.instance ).to.be.instanceOf( MockEditor );
84+
expect( vm.$_instance ).to.be.instanceOf( MockEditor );
8585

8686
wrapper.destroy();
8787
} );
@@ -100,8 +100,8 @@ describe( 'CKEditor Component', () => {
100100

101101
await Vue.nextTick();
102102

103-
expect( vm.instance.config.initialData ).to.equal( 'foo' );
104-
expect( vm.instance.setDataCounter ).to.equal( 0 );
103+
expect( vm.$_instance.config.initialData ).to.equal( 'foo' );
104+
expect( vm.$_instance.setDataCounter ).to.equal( 0 );
105105

106106
wrapper.destroy();
107107
} );
@@ -135,7 +135,7 @@ describe( 'CKEditor Component', () => {
135135

136136
await Vue.nextTick();
137137

138-
expect( vm.instance.isReadOnly ).to.be.true;
138+
expect( vm.$_instance.isReadOnly ).to.be.true;
139139
wrapper.destroy();
140140
} );
141141
} );
@@ -152,7 +152,7 @@ describe( 'CKEditor Component', () => {
152152

153153
await Vue.nextTick();
154154

155-
expect( vm.instance.config ).to.deep.equal( { foo: 'bar' } );
155+
expect( vm.$_instance.config ).to.deep.equal( { foo: 'bar' } );
156156
wrapper.destroy();
157157
} );
158158

@@ -206,7 +206,7 @@ describe( 'CKEditor Component', () => {
206206
it( '#instance should be defined', async () => {
207207
await Vue.nextTick();
208208

209-
expect( vm.instance ).to.be.instanceOf( MockEditor );
209+
expect( vm.$_instance ).to.be.instanceOf( MockEditor );
210210
} );
211211
} );
212212

@@ -218,21 +218,21 @@ describe( 'CKEditor Component', () => {
218218

219219
await Vue.nextTick();
220220

221-
expect( vm.instance.isReadOnly ).to.be.true;
221+
expect( vm.$_instance.isReadOnly ).to.be.true;
222222

223223
wrapper.setProps( { disabled: false } );
224224

225225
await Vue.nextTick();
226226

227-
expect( vm.instance.isReadOnly ).to.be.false;
227+
expect( vm.$_instance.isReadOnly ).to.be.false;
228228

229229
wrapper.destroy();
230230
} );
231231

232232
it( '#value should trigger editor#setData', async () => {
233233
await Vue.nextTick();
234234

235-
const spy = sandbox.spy( vm.instance, 'setData' );
235+
const spy = sandbox.spy( vm.$_instance, 'setData' );
236236
wrapper.setProps( { value: 'foo' } );
237237

238238
await Vue.nextTick();
@@ -263,7 +263,7 @@ describe( 'CKEditor Component', () => {
263263
await Vue.nextTick();
264264

265265
expect( wrapper.emitted().ready.length ).to.equal( 1 );
266-
expect( wrapper.emitted().ready[ 0 ] ).to.deep.equal( [ vm.instance ] );
266+
expect( wrapper.emitted().ready[ 0 ] ).to.deep.equal( [ vm.$_instance ] );
267267
} );
268268

269269
it( 'should emit #destroy when the editor is destroyed', async () => {
@@ -274,7 +274,7 @@ describe( 'CKEditor Component', () => {
274274
wrapper.destroy();
275275

276276
expect( wrapper.emitted().destroy.length ).to.equal( 1 );
277-
expect( wrapper.emitted().destroy[ 0 ] ).to.deep.equal( [ vm.instance ] );
277+
expect( wrapper.emitted().destroy[ 0 ] ).to.deep.equal( [ vm.$_instance ] );
278278
} );
279279

280280
describe( '#input event', () => {
@@ -284,7 +284,7 @@ describe( 'CKEditor Component', () => {
284284

285285
await Vue.nextTick();
286286

287-
const on = vm.instance.model.document.on;
287+
const on = vm.$_instance.model.document.on;
288288
const evtStub = {};
289289

290290
expect( on.calledOnce ).to.be.true;
@@ -299,7 +299,7 @@ describe( 'CKEditor Component', () => {
299299

300300
expect( wrapper.emitted().input.length ).to.equal( 1 );
301301
expect( wrapper.emitted().input[ 0 ] ).to.deep.equal( [
302-
'foo', evtStub, vm.instance
302+
'foo', evtStub, vm.$_instance
303303
] );
304304
} );
305305

@@ -310,7 +310,7 @@ describe( 'CKEditor Component', () => {
310310

311311
await Vue.nextTick();
312312

313-
const on = vm.instance.model.document.on;
313+
const on = vm.$_instance.model.document.on;
314314
const evtStub = {};
315315

316316
expect( on.calledOnce ).to.be.true;
@@ -323,7 +323,7 @@ describe( 'CKEditor Component', () => {
323323

324324
expect( wrapper.emitted().input.length ).to.equal( 1 );
325325
expect( wrapper.emitted().input[ 0 ] ).to.deep.equal( [
326-
'foo', evtStub, vm.instance
326+
'foo', evtStub, vm.$_instance
327327
] );
328328
} );
329329
} );
@@ -333,7 +333,7 @@ describe( 'CKEditor Component', () => {
333333

334334
await Vue.nextTick();
335335

336-
const on = vm.instance.editing.view.document.on;
336+
const on = vm.$_instance.editing.view.document.on;
337337
const evtStub = {};
338338

339339
expect( on.calledTwice ).to.be.true;
@@ -346,7 +346,7 @@ describe( 'CKEditor Component', () => {
346346

347347
expect( wrapper.emitted().focus.length ).to.equal( 1 );
348348
expect( wrapper.emitted().focus[ 0 ] ).to.deep.equal( [
349-
evtStub, vm.instance
349+
evtStub, vm.$_instance
350350
] );
351351
} );
352352

@@ -355,7 +355,7 @@ describe( 'CKEditor Component', () => {
355355

356356
await Vue.nextTick();
357357

358-
const on = vm.instance.editing.view.document.on;
358+
const on = vm.$_instance.editing.view.document.on;
359359
const evtStub = {};
360360

361361
expect( on.calledTwice ).to.be.true;
@@ -368,7 +368,7 @@ describe( 'CKEditor Component', () => {
368368

369369
expect( wrapper.emitted().blur.length ).to.equal( 1 );
370370
expect( wrapper.emitted().blur[ 0 ] ).to.deep.equal( [
371-
evtStub, vm.instance
371+
evtStub, vm.$_instance
372372
] );
373373
} );
374374
} );

Diff for: tests/plugin/integration.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ describe( 'CKEditor plugin', () => {
2222
template: '<ckeditor :editor="editor" @ready="onReady()" v-model="editorData"></ckeditor>',
2323
methods: {
2424
onReady: () => {
25-
const instance = wrapper.vm.$children[ 0 ].instance;
25+
const instance = wrapper.vm.$children[ 0 ].$_instance;
2626

2727
expect( instance ).to.be.instanceOf( ClassicEditor );
2828
expect( instance.getData() ).to.equal( '<p>foo</p>' );

Diff for: tests/plugin/localcomponent.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe( 'CKEditor plugin', () => {
4141

4242
await Vue.nextTick();
4343

44-
expect( wrapperFoo.vm.$children[ 0 ].instance ).to.be.instanceOf( FooEditor );
45-
expect( wrapperBar.vm.$children[ 0 ].instance ).to.be.instanceOf( BarEditor );
44+
expect( wrapperFoo.vm.$children[ 0 ].$_instance ).to.be.instanceOf( FooEditor );
45+
expect( wrapperBar.vm.$children[ 0 ].$_instance ).to.be.instanceOf( BarEditor );
4646
} );
4747
} );

0 commit comments

Comments
 (0)