Search code examples
javascriptjquerydomckeditordom-events

How to remove CKeditor instances after the editor has been removed from the DOM


There have been a few related questions on SO about how to remove CKeditor instances, most using .destroy(). This is fine when the editor is still in the dom, however. I have a situation where a CMS is adding a text area, which I am converting to a CKeditor. the cms moves elements from the dom (on an unrelated event).

I can bind an event to the complete emit of that unrelated event, so that the CKeditor can be re-initialized. All that works fine but when I come to remove those left over instances I get errors, this is how I tried:

for (var name in CKEDITOR.instances) {
    CKEDITOR.instances[name].destroy(true);
}

but it generates a error:

Uncaught TypeError: Cannot read property 'clearCustomData' of null

I have recreated the issue on a jsfiddle You'll see that the code:

  1. creates a ckeditor instance from a textarea
  2. removes the parent dom element
  3. creates new dom elements
  4. tried to remove all current instances
  5. creates a new ckeditor instance

Step 4 generates the error.

n.b. related questions on removing ckeditor instances relate to still existing dom elements where in this situation the dom has been removed. I have no control over the dom element being removed.

Is there a way to bind an event to the ckeditor triggered when it parent dom elements are removed? I'd assume I'd still hit this issue even if that was the case. Any one any idea?

n.b. I am using jQuery in other places in this project, so a solution involving jQuery would be suitable even though I'm not using it in the ckeditor code.

UPDATE:

I did try setting the instances to null, which does work, but doesn't kill the object created on a CKeditor instance. i.e. CKEDITOR.htmlDataProcessor (using 'Profiles -> Heap snapshot' in Chrome dev tools is a good demo of the issue)

UPDATE:

Thanks @oleq for the information, I looked at the discussion but couldn't so how to add to it so updated here:

Please see the image of mem profiles before and after dom changes.

dom changes effecting memory

You'll see the size of the CKEDITOR properties really go up.

I notice that CKEDITOR.instances.editor1.element.$ stores the element the ckeditor has been bound to/fired upon. Would a check for an existing ckeditor instance on that element, which would destroy the existing CKEDITOR.htmlDataProcessor etc objects and recreate before a new instance is added to the text area?

Does that sound like something that would be appropriate or would the fact that this is seen as an edge case mean its too low a priority? I'm happy to put in the work and pull request if deemed a reasonable solution?


Solution

  • The algorithm that controls destruction of CKEditor instances wasn't designed to handle edge cases. The error is thrown at that specific point in wysiwygarea plugin because basically editor.window.getFrame() returns null.

    It's an edge case, already discussed on CKEditor bug tracker.