diff -uprN markup_snippets_orig/markup_snippets.js markup_snippets/markup_snippets.js
--- markup_snippets_orig/markup_snippets.js	1970-01-01 01:00:00.000000000 +0100
+++ markup_snippets/markup_snippets.js	2010-01-28 20:51:51.728389475 +0100
@@ -0,0 +1,61 @@
+// $Id$
+
+/*
+ * Attach AJAX/AHAH event handlers for Wysiwyg integration.
+ *
+ * This code takes care of Wysiwyg integration in D6.
+ * Wysiwyg module needs to be able to detach any attached editor before the
+ * AJAX request is made or it cannot be re-attached afterwards.
+ * Drupal 6 does not have detach behaviors so we need to manually call
+ * Drupal.wysiwygDetach(). Wysiwyg's own behavior won't be able to
+ * re-attach the editor either because the context doesn't include the
+ * format selector so we call Drupal.wysiwygAttach() manually too.
+ * Drupal's jquery.form.js does not trigger 'form-pre-serialize' so we must
+ * re-serialize the form after detaching the editor in 'ajaxSend'.
+ *
+ * @param context
+ *   A DOM element, supplied by Drupal.attachBehaviors().
+ *
+ * This code is based on Drupal.behaviors.attachWysiwyg from Wysiwyg module. 
+ * @see Drupal.behaviors.attachWysiwyg in Wysiwyg module.
+ */
+Drupal.behaviors.markup_snippets = function (context) {
+  var params;
+  // Add a global AJAX listener for attaching/detaching Wysiwyg module.
+  $('#edit-markup-snippets-select-wrapper:not(.markup-snippets-processed)', context).each(function () {
+    $(this).addClass('markup-snippets-processed').bind('ajaxSend', function (event, XMLHttpRequest, ajaxOptions) {
+      if (typeof Drupal.wysiwyg == 'undefined') {
+        return;
+      }
+      // Detach the Wysiwyg module if this is our request.
+      if (ajaxOptions.url == '/markup_snippets/js') {
+        params = $.extend({}, Drupal.wysiwyg.instances['edit-body']);
+        if (params.editor == 'none') {
+          // No editor instance, get parameters from the selected input format.
+          params = Drupal.wysiwyg.getParams($(':input.wysiwyg-field-edit-body:checked, div.wysiwyg-field-edit-body', context).get(0));
+          // Override status to keep the editor disabled when re-attaching.
+          params.status = false;
+        }
+        Drupal.wysiwygDetach(context, params);
+        // Re-serialize the form. Enable the select to include its value.
+        $("#edit-markup-snippets-changed").attr('disabled', false);
+        var formValues =  $('#edit-body').parents('form').formToArray();
+        // Add the operation/clicked button, ahah.js normally does this for us.
+        formValues.push({
+          name: 'op',
+          value: Drupal.settings.ahah['edit-markup-snippets-changed'].button.op,
+        });
+        ajaxOptions.data = $.param(formValues);
+        // Disable the select and the button to avoid multiple paralell posts.
+        $("#edit-markup-snippets-select, #edit-markup-snippets-changed").attr('disabled', true);
+      }
+    }).bind('ajaxComplete', function (event, XMLHttpRequest, ajaxOptions) {
+      // Re-attach the Wysiwyg module if this is our response.
+      if (ajaxOptions.url == '/markup_snippets/js') {
+        Drupal.wysiwygAttach(context, params);
+        // Re-enable the select, the button is automatically enabled by ahah.js.
+        $("#edit-markup-snippets-select").attr('disabled', false)
+      }
+    });
+  });
+}
diff -uprN markup_snippets_orig/markup_snippets.module markup_snippets/markup_snippets.module
--- markup_snippets_orig/markup_snippets.module	2010-01-12 20:20:00.301616772 +0100
+++ markup_snippets/markup_snippets.module	2010-01-29 03:03:56.627838630 +0100
@@ -14,6 +14,11 @@ function markup_snippets_form_alter(&$fo
   
   // make sure we're on a node form and user has permission to use snippets
   if ($form['#id'] == 'node-form' && user_access('use snippets')) {
+    if (module_exists('wysiwyg')) {
+      // Include the Wysiwyg module integration.
+      drupal_add_js(drupal_get_path('module', 'markup_snippets') . '/markup_snippets.js');
+    }
+
     // enforce caching for ahah
     $form['#cache'] = TRUE;
     
@@ -21,15 +26,20 @@ function markup_snippets_form_alter(&$fo
     $type = node_get_types('type', $form['#node']);
     
     // set up a new fieldset above the node body field
-    $form['body_field']['markup_snippets'] = array(
+    $form['markup_snippets'] = array(
       '#type' => 'fieldset',
       '#title' => t('Mark-up Snippets'),
       '#description' => t('Load saved snippets or save the contents of the current !body_label field.', array('!body_label' => $type->body_label)),
-      '#weight' => -100,
+      '#weight' => -1,
       '#collapsible' => TRUE,
       '#collapsed' => TRUE,
     );
     
+    if (module_exists('content')) {
+      // Simple fix for compatibility with CCK's field sorting.
+      $form['markup_snippets']['#weight'] = content_extra_field_weight($form['#node']->type, 'body_field') - 1;
+    }
+
     // set variables for the select list
     $disabled = FALSE;
     $default_label = t('Select a snippet >>');
@@ -47,37 +57,65 @@ function markup_snippets_form_alter(&$fo
     }
     
     // render the actual form field
-    $form['body_field']['markup_snippets']['markup_snippets_select'] = array(
+    $form['markup_snippets']['markup_snippets_select'] = array(
       '#type' => 'select',
       '#title' => t('Select a snippet to use'),
       '#description' => $description,
       '#options' => $options,
       '#default_value' => 0,
       '#disabled' => $disabled,
+    );
+
+    // We need a submit button to add submit handlers to our select.
+    $form['markup_snippets']['markup_snippets_changed'] = array(
+      '#type'  => 'submit',
+      // We do not need to render it, handler is called anyway.
+      '#value' => t('Use snippet'),
+      '#submit' => array('markup_snippets_select_submit'),
       '#ahah' => array(
         'path' => 'markup_snippets/js',
         'wrapper' => 'edit-body-wrapper',
         // default so not needed: 'method' => 'replace',
-        'event' => 'change',
       ),
+      '#disabled' => $disabled,
     );
-    
-    // we need a submit button to add submit handlers to our select
-    /*$form['body_field']['markup_snippets']['changed'] = array(
-      '#type'  => 'submit',
-      '#value' => t('Use snippet'),
-      '#submit' => array('mark_snippets_select_submit'),
 
-    );*/
-    
     // we need a field for naming our snippet
-    $form['body_field']['markup_snippets']['markup_snippets_name'] = array(
+    $form['markup_snippets']['markup_snippets_name'] = array(
       '#type' => 'textfield',
       '#title' => t('Enter a name to save the current snippet'),
       '#size' => 30,
       '#description' => t('If you enter a name in this box then the contents of the !body_label field will be saved as a snippet when you click Save.', array('!body_label' => $type->body_label))
     );
-    
+
+    if ($form_state['values']['op'] == t('Use snippet')) {
+        // Get the selected snippet text and put it in the body.
+        // Doing it here keeps the cach in sync with the rendered form.
+        $mid = $form_state['values']['markup_snippets_select'];
+        if ($mid > 0) {
+          $snippets = markup_snippets_get_snippets(array(), TRUE, $mid);
+          // This is set to become a system variable later so you can choose to
+          // append or replace the snippet to the current contents.
+          $append = FALSE;
+          if ($append){
+            $form['body_field']['body']['#default_value'] = $form_state['values']['body'] . $snippets[$mid]['snippet'];
+          }
+          else {
+            $form['body_field']['body']['#default_value'] = $snippets[$mid]['snippet'];
+          }
+        }
+        else {
+          // If no snippet was selected, override the body using just the posted
+          // value or the old teaser from an edited node may be prepended.
+          $form['body_field']['body']['#default_value'] = $form_state['values']['body'];
+        }
+        // Teaser is always 'included' in the snippet.
+        $form['body_field']['teaser_include']['#default_value'] = TRUE;
+        if (isset($form_state['post']['original_action'])) {
+          // #action was changed because system.module set it to request_uri().
+          $form['#action'] = $form_state['post']['original_action'];
+        }
+    }
   }
 }
 
@@ -399,6 +437,20 @@ function markup_snippets_get_snippets($s
   return $snippets;
 }
 
+/*
+ * Custom submit handler for markup snippet changes.
+ */
+function markup_snippets_select_submit($form, &$form_state) {
+  // Remove form-level handlers so the node is not saved during AHAH requests.
+  unset($form_state['submit_handlers']);
+  // We still allow element level submit handlers to run.
+  form_execute_handlers('submit', $form, $form_state);
+  $node = $form_state['values'];
+  // Set $form_state['node'] for the node form builder.
+  $form_state['node'] = $node;
+  $form_state['rebuild'] = TRUE;
+}
+
 /**
  * Implementation of ahah callback for node form.
  */
@@ -415,10 +467,7 @@ function markup_snippets_js() {
   // causes an error because the node gets locked.
   
   // Preparing to retrieve form from cache
-  // Old line:
-  // $form_state = array('storage' => NULL, 'submitted' => FALSE);
-  // Our replacement:
-  $form_state = array('storage' => NULL, 'rebuild' => TRUE);
+  $form_state = array('storage' => NULL, 'submitted' => FALSE);
   $form_build_id = $_POST['form_build_id'];
   
   // Retrieve the form from the cache
@@ -430,6 +479,10 @@ function markup_snippets_js() {
   $form_state['post'] = $form['#post'] = $_POST;
   $form['#programmed'] = $form['#redirect'] = FALSE;
 
+  _markup_snippets_remove_required_flag($form);
+
+  // Store the #action, system.module will overwrite it using request_uri().
+  $form_state['post']['original_action'] = $form['#action'];
   // Process the form
   drupal_process_form($form_id, $form, $form_state);
   // Rebuild the form
@@ -438,53 +491,14 @@ function markup_snippets_js() {
   // CUSTOM CODE STARTS HERE
   
   // Now we have the latest $form, with the changes made by our
-  // AHAH enabled field - we can now build our mark-up to return
-  
-  // get the node type info we need for our body field
-  $node = $form['#node'];
-  $type = node_get_types('type', $node);
-  
-  // load the snippet from the posted data
-  $mid = $form_state['post']['markup_snippets_select'];
-  $snippet = markup_snippets_get_snippets(array(), TRUE, $mid);
-  
-  // build our new body
-  // this is set to become a system variable later so you can choose to 
-  // append or replace
-  $append = TRUE;
-  if ($append && $form_state['post']['body']) {
-    $body_new = $form_state['post']['body'] . $snippet[$mid]['snippet'];
-  }
-  else {
-    $body_new = $snippet[$mid]['snippet'];
-  }
-  
-  // Check if we need to restore the teaser at the beginning of the body.
-  $include = !isset($node->teaser) || ($node->teaser == substr($node->body, 0, strlen($node->teaser)));
-  
-  // build the returned mark-up, structure from node.module  
-  $body_form['body_field']['body'] = array(
-    '#type' => 'textarea',
-    '#title' => check_plain($type->body_label),
-    '#default_value' => $include,
-    '#value' => $body_new,
-    '#rows' => 20,
-    '#required' => ($type->min_word_count > 0),
-  );
-  
-  $output = drupal_render($body_form);
-  
-  // build the returned mark-up
-  // we are mimicking the output of the node_get_body() function
-  $output = '';
-  $output .= '<label for="edit-body">' . check_plain($type->body_label) . ': </label>';
-  $output .= '<div class="resizeable-textarea"><span>';
-  $output .= '<textarea class="form-textarea resizable textarea-processed" id="edit-body" name="body" rows="20" cols="60">';
-  // switch the body for our new body
-  $output .= $body_new;
-  $output .= '</textarea>';
-  $output .= '</span></div>';
-  
+  // AHAH enabled field - we can now render and return the body markup.
+
+  $changed_field = $form['body_field']['body'];
+  $output = drupal_render($changed_field);
+  // Strip the wrapper div as only its contents need to be replaced.
+  $output = preg_replace('/^<div.*?class="form-item".*?id="[^"]*?-wrapper".*?>/', '', $output);
+  $output = preg_replace('/<\/div>\s*$/', '', $output);
+
   // ALL DONE
 
   // Final rendering callback - send our mark-up back to the div we
@@ -495,3 +509,19 @@ function markup_snippets_js() {
   drupal_get_messages();
 }
 
+/**
+ * Helper function to recursively switch #reqiured to FALSE on form elements.
+ *
+ * When processing forms during an AHAH request we don't want to treat empty
+ * fields as invalid. Setting #required to FALSE makes sure our submit handler
+ * runs. As the form is not actually submitted to the database yet, this is ok.
+ */
+function _markup_snippets_remove_required_flag(&$element) {
+  foreach (element_children($element) as $key) {
+    _markup_snippets_remove_required_flag($element[$key]);
+  }
+  if (isset($element['#required']) && $element['#required']) {
+    $element['#required'] = FALSE;
+  }
+}
+
