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

Commit dd2bb90

Browse files
authored
Merge pull request #44 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 ead6e41 + 65b6ac0 commit dd2bb90

File tree

5 files changed

+154
-0
lines changed

5 files changed

+154
-0
lines changed

tests/inlineeditor.js

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

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

2325
describe( 'InlineEditor', () => {
2426
let editor, editorElement;
@@ -294,4 +296,17 @@ describe( 'InlineEditor', () => {
294296
.then( newEditor => newEditor.destroy() );
295297
} );
296298
} );
299+
300+
describeMemoryUsage( () => {
301+
testMemoryUsage(
302+
'should not grow on multiple create/destroy',
303+
() => InlineEditor
304+
.create( document.querySelector( '#mem-editor' ), {
305+
plugins: [ ArticlePluginSet ],
306+
toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote' ],
307+
image: {
308+
toolbar: [ 'imageStyle:full', 'imageStyle:side', '|', 'imageTextAlternative' ]
309+
}
310+
} ) );
311+
} );
297312
} );

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 InlineEditor from '../../src/inlineeditor';
9+
import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
10+
11+
window.editors = {};
12+
13+
/*
14+
* Memory-leak safe version of inline 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+
InlineEditor
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).

tests/manual/sample.jpg

112 KB
Loading

0 commit comments

Comments
 (0)