-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Removed memory leak caused by CKEDITOR.filter.instances #1770
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix does not cover filters for nested editables, which should be destroyed after destroying the widget, not the whole editor.
CHANGES.md
Outdated
@@ -1,6 +1,12 @@ | |||
CKEditor 4 Changelog | |||
==================== | |||
|
|||
## CKEDITOR 4.9.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update version tag.
core/filter.js
Outdated
* | ||
* @since 4.1 | ||
* @class | ||
* @constructor Creates a filter class instance. | ||
* @param {CKEDITOR.editor/CKEDITOR.filter.allowedContentRules} editorOrRules | ||
* @param {CKEDITOR.editor} owner Editor owning the filter instance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like it. We already have editor
as a first parameter. We could make that change compatible with older versions by allowing to optionally pass rules as a second parameter. It seems like a more elegant solution:
CKEDITOR.filter = function( editorOrRules, rules )
Please also note that optional parameters should be marked with []
(so [owner]
, not owner
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only issue with such approach is the fact that new CKEDITOR.filter( editor )
creates new filter based on editor's features. However I still think that something like new CKEDITOR.filter( editor, {} )
or new CKEDITOR.filter( editor, null )
is more readable than new CKEDITOR.filter( null, editor )
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that it's not beautiful. But let's say you would like to create empty filter and setup it by CKEDITOR.filter#allow
function e.g
var filter = new CKEDITOR.filter();
filter.allow( {...} );
In that case, you won't be able to create a filter with owning editor
- if you try to pass editor
as an argument you will create a filter based on editor
(https://github.com/ckeditor/ckeditor-dev/blob/major/core/filter.js#L168).
We have that case in our code (https://github.com/ckeditor/ckeditor-dev/blob/major/plugins/clipboard/plugin.js#L1347) and it's possible that people could use it in that way also.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually you would be still able to create such filter:
var filter = new CKEDITOR.filter( editor, {} );
filter.allow( {} );
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree it can be done but with that change, we will provide breaking change for our API. If we are ok with that I also prefer new CKEDITOR.filter( editorOrRules, rules )
signature. WDYT @Comandeer?
* @param {Object} obj | ||
* @return {Array} object values. | ||
*/ | ||
objToArray: function( obj ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change does not seem to be directly connected with the fix. Why is it present here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it because this PR is based on #1690. Now I think maybe it shouldn't be changed here as it's a separate issue.
I'm using this function inside unit tests for proposed changes.
Rebased into the latest |
c1de513
to
045ae8e
Compare
I left |
Hmm, the main ticket is about destroying filters in nested editables, so it would be nice to actually implement it. I think that workaround to detect any nested editable still using this filter should be enough. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rebase onto latest major
.
core/filter.js
Outdated
* | ||
* @since 4.1 | ||
* @class | ||
* @constructor Creates a filter class instance. | ||
* @param {CKEDITOR.editor/CKEDITOR.filter.allowedContentRules} editorOrRules | ||
* @param {CKEDITOR.editor} rules This parameter is available since 4.10.0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update version tag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this parameter is not of CKEDITOR.editor
type.
core/filter.js
Outdated
@@ -165,11 +175,12 @@ | |||
// Register filter instance. | |||
CKEDITOR.filter.instances[ this.id ] = this; | |||
|
|||
if ( editorOrRules instanceof CKEDITOR.editor ) { | |||
var editor = this.editor = editorOrRules; | |||
this.editor = editorOrRules instanceof CKEDITOR.editor ? editorOrRules : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not:
var editor = this.editor = editorOrRules instanceof CKEDITOR.editor ? editorOrRules : null;
? With such version there won't be need to change all references to the editor.
tests/core/editor/destroy.js
Outdated
|
||
function countFilters( editor ) { | ||
var filters = bender.tools.objToArray( CKEDITOR.filter.instances ); | ||
return editor ? filters.filter( function( filter ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function won't work in IE8, as there is no Array.prototype.filter
. Our own CKEDITOR.tools.array.filter
should be used here.
@@ -0,0 +1,14 @@ | |||
@bender-tags: bug, 4.9.1, 1722 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update version tag.
@@ -0,0 +1,14 @@ | |||
@bender-tags: widget, bug, 4.10.0, 1722 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update version tag.
8b05322
to
b4755f7
Compare
Rebased onto latest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix looks good, only some bureaucracy left. However it seems that filters are still leaking, due to #1452…
@@ -32,6 +32,7 @@ Fixed Issues: | |||
* [#421](https://github.com/ckeditor/ckeditor-dev/issues/421) Fixed: Expandable [Button](https://ckeditor.com/cke4/addon/button) puts `(Selected)` text at the end of the label when clicked. | |||
* [#1454](https://github.com/ckeditor/ckeditor-dev/issues/1454): Fixed: [Upload Widget](https://ckeditor.com/cke4/addon/uploadwidget) [`onAbort`](https://docs.ckeditor.com/ckeditor4/docs/#!/api/CKEDITOR.fileTools.uploadWidgetDefinition-property-onAbort) method is not called when loader is aborted. | |||
* [#1451](https://github.com/ckeditor/ckeditor-dev/issues/1451): Fixed: Context menu is incorrectly positioned when opened with `Shift-F10`. | |||
* [#1722](https://github.com/ckeditor/ckeditor-dev/issues/1722): [`CKEDITOR.filter.instances`](https://docs.ckeditor.com/ckeditor4/latest/api/CKEDITOR_filter.html#static-property-instances) is causing memory leaks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please create followup ticket that will describe changes in API and reference it in "API Changes" section.
core/filter.js
Outdated
* | ||
* @since 4.1 | ||
* @class | ||
* @constructor Creates a filter class instance. | ||
* @param {CKEDITOR.editor/CKEDITOR.filter.allowedContentRules} editorOrRules | ||
* @param {CKEDITOR.filter.allowedContentRules} rules This parameter is available since 4.10.2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update version and add period at the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also mark this parameter as optional.
core/filter.js
Outdated
* ``` | ||
* | ||
* If filter is only used by a single editor instance, you should pass editor instance alongside with the rules | ||
* so the filter could be removed with {@link CKEDITOR.editor#destroy} method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be additional info about what will happen if editor
is passed without rules
as it changes the behaviour of the constructor in not so obvious way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't enough described by the whole https://github.com/ckeditor/ckeditor-dev/blob/013af363d892680f9c0a2f11765aee45ec09ca2b/core/filter.js#L33-L56 docs? 🤔 However, I added additional info that passing only editor ( without rules ) will also prevent memory leaks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Implements most of ckeditor#1770
What is the purpose of this pull request?
Bug fix
Does your PR contain necessary tests?
All patches which change the editor code must include tests. You can always read more
on PR testing,
how to set the testing environment and
how to create tests
in the official CKEditor documentation.
This PR contains
What changes did you make?
Added additional option to
CKEDITOR.filter
constructor to pass an editor owning filter instance. Changededitor.destroy
function to remove correct editors and refactored plugins usingCKEDITOR.filter
. With this change we are now able to remove orphaned editor filters and prevent memory leak withCKEDITOR.filter.instances
.Additional parameter doesn't look most beautiful because we should probably go with something like
new CKEDITOR.filter( editor, rules)
but it would require to provide breaking change for our API.Based on #1690
Closes #1722, closes #2466