diff --git wysiwyg/editors/ckeditor.inc wysiwyg/editors/ckeditor.inc
index ca293a7..ee21c4b 100644
--- wysiwyg/editors/ckeditor.inc
+++ wysiwyg/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
diff --git wysiwyg/editors/js/ckeditor-3.0.js wysiwyg/editors/js/ckeditor-3.0.js
index d2cf300..aacfc1d 100644
--- wysiwyg/editors/js/ckeditor-3.0.js
+++ wysiwyg/editors/js/ckeditor-3.0.js
@@ -1,6 +1,12 @@
 (function($) {
 
 Drupal.wysiwyg.editor.init.ckeditor = function(settings) {
+  $.debug('inited');
+  $.debug(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 +37,11 @@ Drupal.wysiwyg.editor.init.ckeditor = function(settings) {
  * Attach this editor to a target element.
  */
 Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
+  $.debug('attach');
+//  if (typeof Drupal.wysiwyg.editor.initialized.ckeditor == 'undefined') {
+//    Drupal.wysiwyg.editor.init.ckeditor(settings);
+//  }
+
   // Apply editor instance settings.
   CKEDITOR.config.customConfig = '';
 
diff --git wysiwyg/editors/js/none.js wysiwyg/editors/js/none.js
index 3402024..5e0cf27 100644
--- wysiwyg/editors/js/none.js
+++ wysiwyg/editors/js/none.js
@@ -14,6 +14,7 @@
  *   An object containing editor settings for all enabled editor themes.
  */
 Drupal.wysiwyg.editor.attach.none = function(context, params, settings) {
+  $.debug('attach.none');
   if (params.resizable) {
     var $wrapper = $('#' + params.field).parents('.form-textarea-wrapper:first');
     $wrapper.addClass('resizable');
diff --git wysiwyg/tests/wysiwyg_test.module wysiwyg/tests/wysiwyg_test.module
index c908e29..215d1fe 100644
--- wysiwyg/tests/wysiwyg_test.module
+++ wysiwyg/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'];
+}
+
diff --git wysiwyg/wysiwyg.init.js wysiwyg/wysiwyg.init.js
index 6ccdb31..57e8ef5 100644
--- wysiwyg/wysiwyg.init.js
+++ wysiwyg/wysiwyg.init.js
@@ -6,6 +6,19 @@ 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 + '/';
+        }
+      });
+    });
+    $.debug(window, 'wysiwyg.init.js: BasePath set.');
+  }
+  
   // Determine support for queryCommandEnabled().
   // An exception should be thrown for non-existing commands.
   // Safari and Chrome (WebKit based) return -1 instead.
diff --git wysiwyg/wysiwyg.js wysiwyg/wysiwyg.js
index 72ca156..030d08b 100644
--- wysiwyg/wysiwyg.js
+++ wysiwyg/wysiwyg.js
@@ -45,11 +45,11 @@ Drupal.behaviors.attachWysiwyg = {
     }
 
     $('.wysiwyg', context).once('wysiwyg', function() {
-      if (!this.id || typeof Drupal.settings.wysiwyg.triggers[this.id] === 'undefined') {
+      if (!this.id || typeof settings.wysiwyg.triggers[this.id] === 'undefined') {
         return;
       }
       var $this = $(this);
-      var params = Drupal.settings.wysiwyg.triggers[this.id];
+      var params = settings.wysiwyg.triggers[this.id];
       for (var format in params) {
         params[format].format = format;
         params[format].trigger = this.id;
@@ -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,49 @@ 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 ctools_close_instance = $('#' + params.field).parents('div.ctools-modal-content').find('a.close');
+      var event_sources = [ {"instance" : form_instance, "event" : 'submit'},
+                            {"instance" : ctools_close_instance, "event" : 'click'}];
+
+      for (index = 0; index < event_sources.length; index++) {
+        var instance_data = event_sources[index].instance.data();
+        var event_name = event_sources[index].event;
+        $.debug(event_sources[index].instance, 'binding events for object');
+        $.debug(instance_data, 'data for event ' + event_name);
+
+        // Copy original events from instance and remove the existing handlers.
+        var orig_events = Array();
+        if (instance_data && instance_data.events && instance_data.events[event_name]) {
+          orig_events = instance_data.events[event_name].slice(0);
+          event_sources[index].instance.unbind(event_name);
         }
-        Drupal.wysiwygDetach(context, params[format]);
-      });
+        $.debug(orig_events, 'orig handlers for event ' + event_name);
+
+        // Add in the wysiwyg binding as the first 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]);
+        });
+
+        // Append the original event handlers after the wysiwyg handler
+        for (index2 = 0; index2 < orig_events.length; index2++) {
+          // Have to re-add the original events this way,
+          // for some reason the following doesn't work:
+          // event_sources[index].instance.bind(event_name, orig_events[index2]);
+          var new_event = {};
+          new_event[event_name] = orig_events[index2];
+          event_sources[index].instance.bind(new_event);
+        }
+        $.debug(event_sources[index].instance, 'updated instance');
+      }
     });
   }
 };
@@ -95,7 +127,9 @@ Drupal.behaviors.attachWysiwyg = {
  * @param params
  *   An object containing input format parameters.
  */
-Drupal.wysiwygAttach = function(context, params) {
+Drupal.wysiwygAttach = function(context, params, settings) {
+  $.debug(params, 'wysiwygAttach');
+  $.debug(Drupal.wysiwyg.editor.attach);
   if (typeof Drupal.wysiwyg.editor.attach[params.editor] == 'function') {
     // (Re-)initialize field instance.
     Drupal.wysiwyg.instances[params.field] = {};
@@ -138,6 +172,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);
