Index: filefield.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield.module,v
retrieving revision 1.166
diff -u -r1.166 filefield.module
--- filefield.module	2 Mar 2009 07:27:18 -0000	1.166
+++ filefield.module	9 Mar 2009 02:52:22 -0000
@@ -1,4 +1,5 @@
-<?php  // $Id: filefield.module,v 1.166 2009/03/02 07:27:18 quicksketch Exp $
+<?php
+// $Id: filefield.module,v 1.166 2009/03/02 07:27:18 quicksketch Exp $
 
 /**
  * @file
@@ -468,47 +469,24 @@
     exit;
   }
 
-  // form_get_cache() doesn't yield the original $form_state,
-  // but form_builder() does. Needed for retrieving the file array.
-  $built_form = $form;
-  $built_form_state = $form_state;
-
-  $built_form += array('#post' => $_POST);
-  $built_form = form_builder($_POST['form_id'], $built_form, $built_form_state);
-
-  // Clean ids, so that the same element doesn't get a different element id
-  // when rendered once more further down.
-  form_clean_id(NULL, TRUE);
-
-  // Ask CCK for the replacement form element. Going through CCK gets us
-  // the benefit of nice stuff like '#required' merged in correctly.
-  module_load_include('inc', 'content', 'includes/content.node_form');
-  $field_element = content_field_form($form, $built_form_state, $field, $delta);
-  $delta_element = $field_element[$field_name][0]; // there's only one element in there
+  // Build the form. This calls the file field's #value_callback function and
+  // saves the uploaded file. Since this form is already marked as cached
+  // (the #cache property is TRUE), the cache is updated automatically and we
+  // don't need to call form_set_cache().
+  $args = $form['#parameters'];
+  $form_id = array_shift($args);
+  $form['#post'] = $_POST;
+  $form = form_builder($form_id, $form, $form_state);
 
-  // Add the new element at the right place in the form.
+  // Update the cached form with the new element at the right place in the form.
   if (module_exists('fieldgroup') && ($group_name = _fieldgroup_field_get_group($type_name, $field_name))) {
-    $form[$group_name][$field_name][$delta] = $delta_element;
+    $form_element = $form[$group_name][$delta][$field_name];
   }
   else {
-    $form[$field_name][$delta] = $delta_element;
+    $form_element = $form[$field_name][$delta];
   }
 
-  // Render the form for output.
-  $form += array(
-    '#post' => $_POST,
-    '#programmed' => FALSE,
-  );
-  drupal_alter('form', $form, array(), 'filefield_js');
-  $form_state = array('submitted' => FALSE);
-  $form = form_builder('filefield_js', $form, $built_form_state);
-  $field_form = empty($group_name) ? $form[$field_name] : $form[$group_name][$field_name];
-
-  // We add a div around the new content to tell AHAH to let this fade in.
-  $field_form[$delta]['#prefix'] = '<div class="ahah-new-content">';
-  $field_form[$delta]['#suffix'] = '</div>';
-
-  $output = drupal_render($field_form[$delta]);
+  $output = drupal_render($form_element);
 
   // AHAH is not being nice to us and doesn't know the "other" button (that is,
   // either "Upload" or "Delete") yet. Which in turn causes it not to attach
Index: filefield_field.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield_field.inc,v
retrieving revision 1.14
diff -u -r1.14 filefield_field.inc
--- filefield_field.inc	2 Mar 2009 07:09:32 -0000	1.14
+++ filefield_field.inc	9 Mar 2009 02:52:22 -0000
@@ -94,7 +94,6 @@
       $items[$delta] = array_merge($item, $file);
     }
   }
-  $items = array_values($items); // compact deltas
   return array($field['field_name'] => $items);
 }
 
@@ -113,8 +112,6 @@
     if (empty($items[$delta])) unset($items[$delta]);
     $curfids[] = $item['fid'];
   }
-  $items = array_values($items); // compact deltas
-
 
   // if this is a new node... there are no
   // old items to worry about.
@@ -138,8 +135,9 @@
   foreach ($items as $delta => $item) {
     // For hook_file_references, remember that this is being deleted.
     $item['field_name'] = $field['field_name'];
-    if (field_file_delete($item)) unset($items[$delta]);
-    $items = array_values($items); // compact deltas
+    if (field_file_delete($item)) {
+      unset($items[$delta]);
+    }
   }
 }
 
Index: filefield_widget.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield_widget.inc,v
retrieving revision 1.57
diff -u -r1.57 filefield_widget.inc
--- filefield_widget.inc	2 Mar 2009 07:27:19 -0000	1.57
+++ filefield_widget.inc	9 Mar 2009 02:52:23 -0000
@@ -192,13 +192,57 @@
     unset($element['#title']);
   }
 
-  // Check if a remove button was clicked.
-  $remove_name = $element['#field_name'] .'_'. $element['#delta'] .'_filefield_remove';
-  if (isset($form_state['clicked_button']) && $form_state['clicked_button']['#name'] == $remove_name) {
+  // Set up the buttons first since we need to check if they were clicked.
+  $element['filefield_upload'] = array(
+    '#type' => 'submit',
+    '#value' => t('Upload'),
+    '#process' => array('form_expand_ahah'),
+    '#submit' => array('node_form_submit_build_node'),
+    '#ahah' => array( // with JavaScript
+       'path' => 'filefield/ahah/'.   $element['#type_name'] .'/'. $element['#field_name'] .'/'. $element['#delta'],
+       'wrapper' => $element['#id'] .'-ahah-wrapper',
+       'method' => 'replace',
+       'effect' => 'fade',
+    ),
+    '#field_name' => $element['#field_name'],
+    '#delta' => $element['#delta'],
+    '#type_name' => $element['#type_name'],
+    '#upload_validators' => $element['#upload_validators'],
+    '#weight' => 100,
+    '#post' => $element['#post'],
+  );
+  $element['filefield_remove'] = array(
+    '#name' => $element['#field_name'] .'_'. $element['#delta'] .'_filefield_remove',
+    '#type' => 'submit',
+    '#value' => t('Remove'),
+    '#process' => array('form_expand_ahah'),
+    '#submit' => array('node_form_submit_build_node'),
+    '#ahah' => array( // with JavaScript
+      'path' => 'filefield/ahah/'.   $element['#type_name'] .'/'. $element['#field_name'] .'/'. $element['#delta'],
+      'wrapper' => $element['#id'] .'-ahah-wrapper',
+      'method' => 'replace',
+      'effect' => 'fade',
+    ),
+    '#field_name' => $element['#field_name'],
+    '#delta' => $element['#delta'],
+    '#weight' => 101,
+    '#post' => $element['#post'],
+  );
+
+  // Because the output of this field changes depending on the button clicked,
+  // we need to ask FAPI immediately if the remove button was clicked.
+  // It's not good that we call this private function, but
+  // $form_state['clicked_button'] is only available after this #process
+  // callback is finished.
+  if (_form_button_was_clicked($element['filefield_remove'])) {
     $item = array('fid' => 0, 'list' => $field['list_default'], 'data' => array('description' => ''));
   }
 
-  // figute out our fid...
+  // Set access on the buttons.
+  $element['filefield_upload']['#access'] = empty($item['fid']);
+  $element['filefield_remove']['#access'] = !empty($item['fid']);
+
+  // Figure out our fid...
   $element['fid'] = array('#type' => 'hidden', '#value' =>  $item['fid']);
 
   if ($item['fid'] != 0) {
@@ -254,40 +298,6 @@
   $element['#attributes']['id'] = $element['#id'] .'-ahah-wrapper';
   $element['#prefix'] = '<div '. drupal_attributes($element['#attributes']) .'>';
   $element['#suffix'] = '</div>';
-  $element['filefield_upload'] = array(
-    '#type' => 'submit',
-    '#value' => t('Upload'),
-    '#process' => array('form_expand_ahah'),
-    '#submit' => array('node_form_submit_build_node'),
-    '#ahah' => array( // with JavaScript
-       'path' => 'filefield/ahah/'.   $element['#type_name'] .'/'. $element['#field_name'] .'/'. $element['#delta'],
-       'wrapper' => $element['#id'] .'-ahah-wrapper',
-       'method' => 'replace',
-       'effect' => 'fade',
-    ),
-    '#field_name' => $element['#field_name'],
-    '#delta' => $element['#delta'],
-    '#type_name' => $element['#type_name'],
-    '#upload_validators' => $element['#upload_validators'],
-    '#access' => empty($item['fid']),
-  );
-
-  $element['filefield_remove'] = array(
-    '#name' => $element['#field_name'] .'_'. $element['#delta'] .'_filefield_remove',
-    '#type' => 'submit',
-    '#value' => t('Remove'),
-    '#process' => array('form_expand_ahah'),
-    '#submit' => array('node_form_submit_build_node'),
-    '#ahah' => array( // with JavaScript
-      'path' => 'filefield/ahah/'.   $element['#type_name'] .'/'. $element['#field_name'] .'/'. $element['#delta'],
-      'wrapper' => $element['#id'] .'-ahah-wrapper',
-      'method' => 'replace',
-      'effect' => 'fade',
-    ),
-    '#field_name' => $element['#field_name'],
-    '#delta' => $element['#delta'],
-    '#access' => !empty($item['fid']),
-  );
 
   return $element;
 }
