--- editors/ckeditor.inc
+++ editors/ckeditor.inc
@@ -142,6 +142,7 @@ function wysiwyg_ckeditor_settings($editor, $config, $theme) {
     // @todo Check whether completely disabling ProcessHTMLEntities is an option.
     'entities_latin' => FALSE,
     'entities_greek' => FALSE,
+    'global_basepath_var' => 'CKEDITOR_BASEPATH',
   );
 
   // Add HTML block format settings; common block formats are already predefined
--- editors/js/ckeditor-3.0.js
+++ editors/js/ckeditor-3.0.js
@@ -1,6 +1,10 @@
 (function($) {
 
 Drupal.wysiwyg.editor.init.ckeditor = function(settings) {
+  window.CKEDITOR_BASEPATH = settings.global.editorBasePath + '/';
+  CKEDITOR.basePath = window.CKEDITOR_BASEPATH;
+//  Drupal.wysiwyg.editor['initialized']['ckeditor'] = true;
+
   // Plugins must only be loaded once. Only the settings from the first format
   // will be used but they're identical anyway.
   var registeredPlugins = {};
@@ -31,6 +35,10 @@ Drupal.wysiwyg.editor.init.ckeditor = function(settings) {
  * Attach this editor to a target element.
  */
 Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
+//  if (typeof Drupal.wysiwyg.editor.initialized.ckeditor == 'undefined') {
+//    Drupal.wysiwyg.editor.init.ckeditor(settings);
+//  }
+
   // Apply editor instance settings.
   CKEDITOR.config.customConfig = '';
 
--- editors/js/tinymce-3.js
+++ editors/js/tinymce-3.js
@@ -50,6 +50,8 @@ Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) {
   ed.onEvent.add(function(ed, e) {
     Drupal.wysiwyg.activeId = ed.id;
   });
+  // Tell TinyMCE DOM has been loaded for AJAX
+  tinymce.dom.Event.domLoaded = true;
   // Make toolbar buttons wrappable (required for IE).
   ed.onPostRender.add(function (ed) {
     var $toolbar = $('<div class="wysiwygToolbar"></div>');
--- tests/wysiwyg_test.module
+++ tests/wysiwyg_test.module
@@ -5,3 +5,47 @@
  * Testing functionality for Wysiwyg module.
  */
 
+/**
+ * Implements hook_menu().
+ */
+function wysiwyg_test_menu() {
+  $items['wysiwyg-test/ajax'] = array(
+    'title' => 'Ajaxified form',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('wysiwyg_test_ajax_form'),
+    'access callback' => TRUE,
+  );
+  return $items;
+}
+
+/**
+ * Form constructor for an ajaxified form lazy-loading a textarea.
+ */
+function wysiwyg_test_ajax_form($form, &$form_state) {
+  $form['enable'] = array(
+    '#type' => 'checkbox',
+    '#title' => 'Load textarea',
+    '#ajax' => array(
+      'callback' => 'wysiwyg_test_ajax_form_callback',
+      'wrapper' => 'ajax-wrapper',
+    ),
+  );
+  $form['wrapper'] = array(
+    '#type' => 'container',
+    '#id' => 'ajax-wrapper',
+  );
+  return $form;
+}
+
+/**
+ * #ajax callback for wysiwyg_test_ajax_form().
+ */
+function wysiwyg_test_ajax_form_callback($form, &$form_state) {
+  $form['body'] = array(
+    '#type' => 'text_format',
+    '#default_value' => '',
+  );
+  form_builder($form['form_id']['#value'], $form, $form_state);
+  return $form['body'];
+}
+
--- wysiwyg.init.js
+++ wysiwyg.init.js
@@ -6,6 +6,18 @@ Drupal.wysiwyg.editor = Drupal.wysiwyg.editor || { 'init': {}, 'attach': {}, 'de
 Drupal.wysiwyg.plugins = Drupal.wysiwyg.plugins || {};
 
 (function ($) {
+  // See if the current editor requires a global basepath variable
+  // to be set before loading.
+  if (Drupal.settings.wysiwyg) {
+    $.each(Drupal.settings.wysiwyg.configs, function(editor_index, editor_value) {
+      $.each(editor_value, function(format_index, format_value){
+        if (format_value.global_basepath_var) {
+          window[format_value.global_basepath_var] = Drupal.settings.wysiwyg.configs[editor_index].global.editorBasePath + '/';
+        }
+      });
+    });
+  }  
+
   // Determine support for queryCommandEnabled().
   // An exception should be thrown for non-existing commands.
   // Safari and Chrome (WebKit based) return -1 instead.
--- wysiwyg.js
+++ wysiwyg.js
@@ -59,7 +59,7 @@ Drupal.behaviors.attachWysiwyg = {
       // Directly attach this editor, if the input format is enabled or there is
       // only one input format at all.
       if ($this.is(':input')) {
-        Drupal.wysiwygAttach(context, params[format]);
+        Drupal.wysiwygAttach(context, params[format], settings);
       }
       // Attach onChange handlers to input format selector elements.
       if ($this.is('select')) {
@@ -67,17 +67,40 @@ Drupal.behaviors.attachWysiwyg = {
           // If not disabled, detach the current and attach a new editor.
           Drupal.wysiwygDetach(context, params[format]);
           format = 'format' + this.value;
-          Drupal.wysiwygAttach(context, params[format]);
+          Drupal.wysiwygAttach(context, params[format], settings);
         });
       }
-      // Detach any editor when the containing form is submitted.
-      $('#' + params.field).parents('form').submit(function (event) {
-        // Do not detach if the event was cancelled.
-        if (event.isDefaultPrevented()) {
-          return;
+
+      var form_instance = $('#' + params.field).parents('form');
+      var event_sources = [ {'instance' : form_instance, 'event' : 'submit'} ];
+
+      // CTools modal content support
+      var ctools_modal_content = $('#' + params.field).closest('div.ctools-modal-content');
+      if (ctools_modal_content.length > 0) {
+        event_sources[0].index = 0;
+        var ctools_close_instance = ctools_modal_content.find('a.close');
+        event_sources.push({'instance' : ctools_close_instance, 'event' : 'click', "index" : 0});
+      }
+
+      for (index = 0; index < event_sources.length; index++) {
+        var event_name = event_sources[index].event;
+
+        // Append handler
+        event_sources[index].instance.bind(event_name, function (event) {
+         // Do not detach if the event was cancelled.
+          if (event.isDefaultPrevented()) {
+            return;
+          }
+          Drupal.wysiwygDetach(context, params[format]);
+        });
+
+        // Insert our handler at a specific position
+        var events_data = event_sources[index].instance.data('events');
+        var event_handlers = events_data[event_name];
+        if (typeof event_sources[index].index == 'number' && event_handlers.length > 1) {
+          event_handlers.splice(event_sources[index].index, 0, event_handlers.pop());
         }
-        Drupal.wysiwygDetach(context, params[format]);
-      });
+      }
     });
   },
 
@@ -102,7 +125,7 @@ Drupal.behaviors.attachWysiwyg = {
  * @param params
  *   An object containing input format parameters.
  */
-Drupal.wysiwygAttach = function(context, params) {
+Drupal.wysiwygAttach = function(context, params, settings) {
   if (typeof Drupal.wysiwyg.editor.attach[params.editor] == 'function') {
     // (Re-)initialize field instance.
     Drupal.wysiwyg.instances[params.field] = {};
@@ -145,6 +168,9 @@ Drupal.wysiwygAttach = function(context, params) {
  *   An object containing input format parameters.
  */
 Drupal.wysiwygDetach = function(context, params) {
+  if (typeof Drupal.wysiwyg.instances[params.field] == 'undefined') {
+    return;
+  }
   var editor = Drupal.wysiwyg.instances[params.field].editor;
   if (jQuery.isFunction(Drupal.wysiwyg.editor.detach[editor])) {
     Drupal.wysiwyg.editor.detach[editor](context, params);
