Index: modules/field/field.form.inc
=========================================================
--- modules/field/field.form.inc	(revision 1.5)
+++ modules/field/field.form.inc	Working Copy
@@ -199,7 +199,10 @@
         // Submit callback for disabled JavaScript.
         '#submit' => array('field_add_more_submit'),
         '#ahah' => array(
-          'path' => 'field/js_add_more/' . $bundle_name_url_css . '/' . $field_name_url_css,
+          // TODO : Once 'callback' is accepted as the prefered implementation,
+          // remove the 'path' attribute.
+          //'path' => 'field/js_add_more/' . $bundle_name_url_css . '/' . $field_name_url_css,
+          'callback' => 'field_add_more_ahah',
           'wrapper' => $field_name_url_css . '-wrapper',
           'method' => 'replace',
           'effect' => 'fade',
@@ -304,6 +307,9 @@
 
 /**
  * Menu callback for AHAH addition of new empty widgets.
+ * 
+ * TODO : Remove this function and its addition in field_menu() once 
+ * field_add_more_ahah() is accepted.
  */
 function field_add_more_js($bundle_name, $field_name) {
   // Arguments are coming from the url, so we translate back dashes.
@@ -421,3 +427,47 @@
   drupal_json(array('status' => TRUE, 'data' => $output));
   exit;
 }
+
+/**
+ * AHAH callback for addition of new empty widgets.
+ * 
+ * TODO : There is no validation here to check that the cardinality is unlimited.
+ * Can we assume that FAPI and form_ahah_callback() provides a sufficient 
+ * control on not running this if the button isn't part of the form, or 
+ * do we need to do something special in one of the validate functions 
+ * that runs before we enter this callback?
+ */
+function field_add_more_ahah($form, $form_state) {
+  $field_name = $form_state['clicked_button']['#field_name'];
+  $bundle_name = $form_state['clicked_button']['#bundle'];
+  
+  // Retrieve field information.
+  $field = $form['#fields'][$field_name]['field'];
+  $instance = $form['#fields'][$field_name]['instance'];
+  $form_path = $form['#fields'][$field_name]['form_path'];
+
+  // Fetch the form element that needs rendering.
+  $field_form = $form;
+  foreach ($form_path as $key) {
+    $field_form = $field_form[$key];
+  }
+  
+  // We add a div around the new field item to receive the ahah effect.
+  $delta = max(element_children($field_form));
+  $field_form[$delta]['#prefix'] = '<div class="ahah-new-content">' . (isset($field_form[$delta]['#prefix']) ? $field_form[$delta]['#prefix'] : '');
+  $field_form[$delta]['#suffix'] = (isset($field_form[$delta]['#suffix']) ? $field_form[$delta]['#suffix'] : '') . '</div>';
+  // Prevent duplicate wrapper.
+  unset($field_form['#prefix'], $field_form['#suffix']);
+
+  // If a newly inserted widget contains AHAH behaviors, they normally won't
+  // work because AHAH doesn't know about those - it just attaches to the exact
+  // form elements that were initially specified in the Drupal.settings object.
+  // The new ones didn't exist then, so we need to update Drupal.settings
+  // by ourselves in order to let AHAH know about those new form elements.
+  $javascript = drupal_add_js(NULL, NULL);
+  $output_js = isset($javascript['setting']) ? '<script type="text/javascript">jQuery.extend(Drupal.settings, ' . drupal_to_js(call_user_func_array('array_merge_recursive', $javascript['setting'])) . ');</script>' : '';
+
+  $output = theme('status_messages') . drupal_render($field_form) . $output_js;
+  drupal_json(array('status' => TRUE, 'data' => $output));
+  exit;
+}
