From e282f0b661e78c1665b225157ef850b0badbab35 Mon Sep 17 00:00:00 2001 From: Hamish Friedlander Date: Tue, 20 Aug 2013 15:49:04 +1200 Subject: [PATCH] FIX Two memory leaks with HtmlEditorField We werent calling tinyMCE.Editor.destroy, which is needed to clean up event bindings. The advanced theme also wasnt cleaning up after itself on destroy properly --- javascript/HtmlEditorField.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/javascript/HtmlEditorField.js b/javascript/HtmlEditorField.js index fa6eda2ff..fe3da6bb4 100644 --- a/javascript/HtmlEditorField.js +++ b/javascript/HtmlEditorField.js @@ -21,6 +21,7 @@ ss.editorWrappers.tinyMCE = (function() { init: function(config) { if(!ss.editorWrappers.tinyMCE.initialized) { tinyMCE.init(config); + ss.editorWrappers.tinyMCE.initialized = true; } }, @@ -62,9 +63,25 @@ ss.editorWrappers.tinyMCE = (function() { // Patch TinyMCE events into underlying textarea field. this.instance.onInit.add(function(ed) { + if(!ss.editorWrappers.tinyMCE.patched) { + // Not ideal, but there's a memory leak we need to patch + var originalDestroy = tinymce.themes.AdvancedTheme.prototype.destroy; + + tinymce.themes.AdvancedTheme.prototype.destroy = function() { + originalDestroy.apply(this, arguments); + + if (this.statusKeyboardNavigation) { + this.statusKeyboardNavigation.destroy(); + this.statusKeyboardNavigation = null; + } + } + + ss.editorWrappers.tinyMCE.patched = true; + } + jQuery(ed.getElement()).trigger('editorinit'); - // Periodically check for inline changes when focused, + // Periodically check for inline changes when focused, // since TinyMCE's onChange only fires on certain actions // like inserting a new paragraph, as opposed to any user input. // This also works around an issue where the "save" button @@ -270,6 +287,7 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE; var ed = tinyMCE.get(this.attr('id')); if (ed) { ed.remove(); + ed.destroy(); // TinyMCE leaves behind events. We should really fix TinyMCE, but lets brute force it for now $.each(jQuery.cache, function(){