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

Commit c959daf

Browse files
authored
Merge pull request #25 from ckeditor/t/ckeditor5/1341
Fix: There should be no memory leaks when the editor is created and destroyed (see ckeditor/ckeditor5#1341).
2 parents 513260d + af84bb7 commit c959daf

File tree

4 files changed

+154
-0
lines changed

4 files changed

+154
-0
lines changed

tests/ballooneditor.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import ElementApiMixin from '@ckeditor/ckeditor5-core/src/editor/utils/elementap
2020
import RootElement from '@ckeditor/ckeditor5-engine/src/model/rootelement';
2121

2222
import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
23+
import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
24+
import { describeMemoryUsage, testMemoryUsage } from '@ckeditor/ckeditor5-core/tests/_utils/memory';
2325

2426
describe( 'BalloonEditor', () => {
2527
let editor, editorElement;
@@ -313,4 +315,17 @@ describe( 'BalloonEditor', () => {
313315
.then( newEditor => newEditor.destroy() );
314316
} );
315317
} );
318+
319+
describeMemoryUsage( () => {
320+
testMemoryUsage(
321+
'should not grow on multiple create/destroy',
322+
() => BalloonEditor
323+
.create( document.querySelector( '#mem-editor' ), {
324+
plugins: [ ArticlePluginSet ],
325+
toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote' ],
326+
image: {
327+
toolbar: [ 'imageStyle:full', 'imageStyle:side', '|', 'imageTextAlternative' ]
328+
}
329+
} ) );
330+
} );
316331
} );

tests/manual/memory.html

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<p>
2+
<button id="destroyEditors">Destroy editor</button>
3+
<button id="initEditors">Init editors</button>
4+
</p>
5+
6+
<div id="editor-1" contenteditable="true" class="custom-class" custom-attr="foo">
7+
<h2>Editor 1</h2>
8+
<p>This is an editor instance. And there's <a href="http://ckeditor.com">some link</a>.</p>
9+
</div>
10+
11+
<div id="editor-2" class="custom-class" custom-attr="foo">
12+
<h2>Editor 2</h2>
13+
<p>This is another editor instance.</p>
14+
<img src="sample.jpg" />
15+
<p>
16+
Unlike Editor 1 it doesn't have contenteditable=true initially.
17+
Check if it's editable after initializing the editors and back to non-editable after destroying them.
18+
</p>
19+
</div>
20+
21+
<style>
22+
.custom-class {
23+
margin-top: 100px;
24+
margin-left: 100px;
25+
margin-bottom: 100px;
26+
width: 450px;
27+
}
28+
</style>

tests/manual/memory.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3+
* For licensing, see LICENSE.md.
4+
*/
5+
6+
/* globals console:false, document, window */
7+
8+
import BalloonEditor from '../../src/ballooneditor';
9+
import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
10+
11+
window.editors = {};
12+
13+
/*
14+
* Memory-leak safe version of balloon editor manual test does not:
15+
* - define global variables (such as let editor; in main file scope)
16+
* - console.log() objects
17+
* - add event listeners with () => {} methods which reference other
18+
*/
19+
function initEditors() {
20+
init( '#editor-1' );
21+
init( '#editor-2' );
22+
23+
document.getElementById( 'destroyEditors' ).addEventListener( 'click', destroyEditors );
24+
25+
function init( selector ) {
26+
BalloonEditor
27+
.create( document.querySelector( selector ), {
28+
plugins: [ ArticlePluginSet ],
29+
toolbar: {
30+
items: [
31+
'heading',
32+
'|',
33+
'bold',
34+
'italic',
35+
'link',
36+
'bulletedList',
37+
'numberedList',
38+
'blockQuote',
39+
'insertTable',
40+
'mediaEmbed',
41+
'undo',
42+
'redo'
43+
]
44+
},
45+
image: {
46+
toolbar: [
47+
'imageStyle:full',
48+
'imageStyle:side',
49+
'|',
50+
'imageTextAlternative'
51+
]
52+
},
53+
table: {
54+
contentToolbar: [
55+
'tableColumn',
56+
'tableRow',
57+
'mergeTableCells'
58+
]
59+
}
60+
} )
61+
.then( editor => {
62+
window.editors[ selector ] = editor;
63+
} )
64+
.catch( err => {
65+
console.error( err.stack );
66+
} );
67+
}
68+
69+
function destroyEditors() {
70+
for ( const selector in window.editors ) {
71+
window.editors[ selector ].destroy().then( () => {
72+
window.editors[ selector ] = undefined;
73+
} );
74+
}
75+
76+
document.getElementById( 'destroyEditors' ).removeEventListener( 'click', destroyEditors );
77+
}
78+
}
79+
80+
document.getElementById( 'initEditors' ).addEventListener( 'click', initEditors );

tests/manual/memory.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
1. Open DevTools on Chrome.
2+
2. Go to Memory tab.
3+
3. Select "Heap snapshot" profiling type.
4+
4. Click "Collect Garbage" (trash icon) and "Clear all profiles" (don't go icon).
5+
5. Record heap snapshot ("Take heap snapshot" a record icon).
6+
6. Repeat multiple times:
7+
- click "Init editor",
8+
- wait to editor show up ,
9+
- click "Destroy editor".
10+
7. Record heap snapshot again.
11+
8. Compare Snapshot 1 with Snapshot 2 and look for:
12+
- "detached" - HTML Elements/DOM nodes
13+
- "EventListener" - there should be only 1
14+
- Any CKEditor5 classes instances like "Editor" or "LivePosition"
15+
16+
## Notes:
17+
18+
* Browser extensions might attach event listeners to the DOM so the safest way to run this test is by running Chrome from command line:
19+
20+
```
21+
google-chrome \
22+
--enable-precise-memory-info \
23+
--disable-extensions \
24+
--disable-plugins \
25+
--incognito \
26+
http://localhost:8125
27+
```
28+
29+
The above will run Chrome without extensions or plugins in incognito mode and open manual tests page.
30+
31+
* Close any running Chrome instance beforehand because otherwise it will open a tab in currently opened Chrome (look for "Opening in existing browser session." in command line).

0 commit comments

Comments
 (0)