=== modified file 'modules/comment/comment.module'
--- modules/comment/comment.module	2008-01-04 15:11:59 +0000
+++ modules/comment/comment.module	2008-01-05 17:43:41 +0000
@@ -1240,7 +1240,12 @@ function comment_validate($edit) {
 function comment_form(&$form_state, $edit, $title = NULL) {
   global $user;
 
-  $op = isset($_POST['op']) ? $_POST['op'] : '';
+  if (isset($form_state['comment_preview'])) {
+    $form['#prefix'] = $form_state['comment_preview'];
+  }
+  if (isset($form_state['comment'])) {
+    $edit = (array)$form_state['comment'] + $edit;
+  }
   $node = node_load($edit['nid']);
 
   if (!$user->uid && variable_get('comment_anonymous_'. $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT) != COMMENT_ANONYMOUS_MAYNOT_CONTACT) {
@@ -1384,17 +1389,21 @@ function comment_form(&$form_state, $edi
   // Only show save button if preview is optional or if we are in preview mode.
   // We show the save button in preview mode even if there are form errors so that
   // optional form elements (e.g., captcha) can be updated in preview mode.
-  if (!form_get_errors() && ((variable_get('comment_preview_'. $node->type, COMMENT_PREVIEW_REQUIRED) == COMMENT_PREVIEW_OPTIONAL) || ($op == t('Preview')) || ($op == t('Save')))) {
-    $form['submit'] = array('#type' => 'submit', '#value' => t('Save'), '#weight' => 19);
-  }
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'),
+    '#weight' => 19,
+    '#access' => !form_get_errors() && (variable_get('comment_preview_'. $node->type, COMMENT_PREVIEW_REQUIRED) == COMMENT_PREVIEW_OPTIONAL || isset($form_state['comment_preview'])),
+  );
 
-  $form['preview'] = array('#type' => 'button', '#value' => t('Preview'), '#weight' => 20);
+  $form['preview'] = array(
+    '#type' => 'submit',
+    '#value' => t('Preview'),
+    '#weight' => 20,
+    '#submit' => array('comment_form_build_preview'),
+  );
   $form['#token'] = 'comment'. $edit['nid'] . (isset($edit['pid']) ? $edit['pid'] : '');
 
-  if ($op == t('Preview')) {
-    $form['#after_build'] = array('comment_form_add_preview');
-  }
-
   if (empty($edit['cid']) && empty($edit['pid'])) {
     $form['#action'] = url('comment/reply/'. $edit['nid']);
   }
@@ -1419,7 +1428,7 @@ function comment_form_box($edit, $title 
  *
  * @ingroup forms
  */
-function comment_form_add_preview($form, &$form_state) {
+function comment_form_build_preview($form, &$form_state) {
   global $user;
   $edit = $form_state['values'];
   drupal_set_title(t('Preview comment'));
@@ -1427,56 +1436,34 @@ function comment_form_add_preview($form,
   $output = '';
   $node = node_load($edit['nid']);
 
-  // Invoke full validation for the form, to protect against cross site
-  // request forgeries (CSRF) and setting arbitrary values for fields such as
-  // the input format. Preview the comment only when form validation does not
-  // set any errors.
-  drupal_validate_form($form['form_id']['#value'], $form, $form_state);
-  if (!form_get_errors()) {
-    _comment_form_submit($edit);
-    $comment = (object)$edit;
-
-    // Attach the user and time information.
-    if (!empty($edit['author'])) {
-      $account = user_load(array('name' => $edit['author']));
-    }
-    elseif ($user->uid && !isset($edit['is_anonymous'])) {
-      $account = $user;
-    }
-    if (!empty($account)) {
-      $comment->uid = $account->uid;
-      $comment->name = check_plain($account->name);
-    }
-    elseif (empty($comment->name)) {
-      $comment->name = variable_get('anonymous', t('Anonymous'));
-    }
-    $comment->timestamp = !empty($edit['timestamp']) ? $edit['timestamp'] : time();
-    $output .= theme('comment_view', $comment, $node);
-  }
-  $form['comment_preview'] = array(
-    '#value' => $output,
-    '#weight' => -100,
-    '#prefix' => '<div class="preview">',
-    '#suffix' => '</div>',
-  );
+  _comment_form_submit($edit);
+  $comment = (object)$edit;
 
-  $output = '';
+  // Attach the user and time information.
+  if (!empty($edit['author'])) {
+    $account = user_load(array('name' => $edit['author']));
+  }
+  elseif ($user->uid && !isset($edit['is_anonymous'])) {
+    $account = $user;
+  }
+  if (!empty($account)) {
+    $comment->uid = $account->uid;
+    $comment->name = check_plain($account->name);
+  }
+  elseif (empty($comment->name)) {
+    $comment->name = variable_get('anonymous', t('Anonymous'));
+  }
+  $comment->timestamp = !empty($edit['timestamp']) ? $edit['timestamp'] : time();
 
   if ($edit['pid']) {
     $comment = db_fetch_object(db_query('SELECT c.*, u.uid, u.name AS registered_name, u.signature, u.picture, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = %d', $edit['pid'], COMMENT_PUBLISHED));
     $comment = drupal_unpack($comment);
     $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
-    $output .= theme('comment_view', $comment, $node);
-  }
-  else {
-    $suffix = empty($form['#suffix']) ? '' : $form['#suffix'];
-    $form['#suffix'] = $suffix . node_view($node);
-    $edit['pid'] = 0;
   }
 
-  $form['comment_preview_below'] = array('#value' => $output, '#weight' => 100);
-
-  return $form;
+  $form_state['comment_preview'] = theme('comment_view', $comment, $node);
+  $form_state['comment'] = $comment;
+  $form_state['rebuild'] = TRUE;
 }
 
 /**
@@ -1758,14 +1745,14 @@ function theme_comment_thread_expanded($
 function theme_comment_post_forbidden($node) {
   global $user;
   static $authenticated_post_comments;
-  
+
   if (!$user->uid) {
     if (!isset($authenticated_post_comments)) {
       // We only output any link if we are certain, that users get permission
       // to post comments by logging in. We also locally cache this information.
       $authenticated_post_comments = array_key_exists(DRUPAL_AUTHENTICATED_RID, user_roles(TRUE, 'post comments') + user_roles(TRUE, 'post comments without approval'));
     }
-    
+
     if ($authenticated_post_comments) {
       // We cannot use drupal_get_destination() because these links
       // sometimes appear on /node and taxonomy listing pages.

