Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.386
diff -u -p -r1.386 form.inc
--- includes/form.inc	16 Oct 2009 19:20:34 -0000	1.386
+++ includes/form.inc	18 Oct 2009 01:33:23 -0000
@@ -1985,110 +1985,6 @@ function form_process_radios($element) {
 }
 
 /**
- * Add text format selector to text elements with the #text_format property.
- *
- * The #text_format property should be the ID of an text format, found in
- * {filter_format}.format, which gets passed to filter_form().
- *
- * If the property #text_format is set, the form element will be expanded into
- * two separate form elements, one holding the content of the element, and the
- * other holding the text format selector. The original element is shifted into
- * a child element, but is otherwise unaltered, so that the format selector is
- * at the same level as the text field which it affects.
- *
- * For example:
- * @code
- *   // A simple textarea, such as a node body.
- *   $form['body'] = array(
- *     '#type' => 'textarea',
- *     '#title' => t('Body'),
- *     '#text_format' => isset($node->format) ? $node->format : filter_default_format(),
- *   );
- * @endcode
- *
- * Becomes:
- * @code
- *   $form['body'] = array(
- *     // Type switches to 'markup', as we're only interested in submitting the child elements.
- *     '#type' => 'markup',
- *     // 'value' holds the original element.
- *     'value' => array(
- *       '#type' => 'textarea',
- *       '#title' => t('Body'),
- *       '#parents' => array('body'),
- *     ),
- *     // 'format' holds the text format selector.
- *     'format' => array(
- *       '#parents' => array('body_format'),
- *       ...
- *     ),
- *   );
- * @endcode
- *
- * And would result in:
- * @code
- *   // Original, unaltered form element value.
- *   $form_state['values']['body'] = 'Example content';
- *   // Chosen text format.
- *   $form_state['values']['body_format'] = 1;
- * @endcode
- *
- * @see system_element_info(), filter_form()
- */
-function form_process_text_format($element) {
-  if (isset($element['#text_format'])) {
-    // Determine the form element parents and element name to use for the input
-    // format widget. This simulates the 'element' and 'element_format' pair of
-    // parents that filter_form() expects.
-    $element_parents = $element['#parents'];
-    $element_name = array_pop($element_parents);
-    $element_parents[] = $element_name . '_format';
-
-    // We need to break references, otherwise form_builder recurses infinitely.
-    $element['value'] = (array)$element;
-    $element['value']['#weight'] = 0;
-    unset($element['value']['#description']);
-    $element['#type'] = 'markup';
-    $element['#theme'] = NULL;
-    $element['#theme_wrappers'] = array('text_format_wrapper');
-    $element['format'] = filter_form($element['#text_format'], 1, $element_parents);
-
-    // We need to clear the #text_format from the new child otherwise we
-    // would get into an infinite loop.
-    unset($element['value']['#text_format']);
-  }
-  return $element;
-}
-
-/**
- * Theme a text format form element.
- *
- * @param $variables
- *   An associative array containing:
- *   - element: An associative array containing the properties of the element.
- *     Properties used: #children, #description
- *
- * @return
- *   A string representing the form element.
- *
- * @ingroup themeable
- */
-function theme_text_format_wrapper($variables) {
-  $element = $variables['element'];
-  $output = '<div class="text-format-wrapper">' . "\n";
-
-  $output .= $element['#children'] . "\n";
-
-  if (!empty($element['#description'])) {
-    $output .= '<div class="description">' . $element['#description'] . "</div>\n";
-  }
-
-  $output .= "</div>\n";
-
-  return $output;
-}
-
-/**
  * Theme a checkbox form element.
  *
  * @param $variables
Index: modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.392
diff -u -p -r1.392 block.module
--- modules/block/block.module	17 Oct 2009 05:50:28 -0000	1.392
+++ modules/block/block.module	18 Oct 2009 03:32:03 -0000
@@ -193,7 +193,7 @@ function block_block_info() {
  * Implement hook_block_configure().
  */
 function block_block_configure($delta = 0) {
-  $custom_block = array('format' => filter_default_format());
+  $custom_block = array('format' => filter_format_default());
   if ($delta) {
     $custom_block = block_custom_block_get($delta);
   }
@@ -430,10 +430,10 @@ function block_custom_block_form($edit =
   );
   $form['body_field']['#weight'] = -17;
   $form['body_field']['body'] = array(
-    '#type' => 'textarea',
+    '#type' => 'textarea_format',
     '#title' => t('Block body'),
     '#default_value' => $edit['body'],
-    '#text_format' => isset($edit['format']) ? $edit['format'] : filter_default_format(),
+    '#format' => isset($edit['format']) ? $edit['format'] : filter_format_default(),
     '#rows' => 15,
     '#description' => t('The content of the block as shown to the user.'),
     '#required' => TRUE,
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.793
diff -u -p -r1.793 comment.module
--- modules/comment/comment.module	17 Oct 2009 05:50:28 -0000	1.793
+++ modules/comment/comment.module	18 Oct 2009 03:32:09 -0000
@@ -1846,11 +1846,11 @@ function comment_form($form, &$form_stat
   }
 
   $form['comment'] = array(
-    '#type' => 'textarea',
+    '#type' => 'textarea_format',
     '#title' => t('Comment'),
     '#rows' => 15,
     '#default_value' => $default,
-    '#text_format' => isset($comment->format) ? $comment->format : filter_default_format(),
+    '#format' => isset($comment->format) ? $comment->format : filter_format_default(),
     '#required' => TRUE,
   );
 
Index: modules/field/modules/text/text.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/text/text.module,v
retrieving revision 1.33
diff -u -p -r1.33 text.module
--- modules/field/modules/text/text.module	15 Oct 2009 12:44:34 -0000	1.33
+++ modules/field/modules/text/text.module	18 Oct 2009 05:47:19 -0000
@@ -548,7 +548,6 @@ function text_element_info() {
     '#delta' => 0,
     '#process' => array('text_textarea_elements_process'),
     '#theme_wrappers' => array('text_textarea'),
-    '#filter_value' => filter_default_format(),
   );
   $types['text_textarea_with_summary'] = array(
     '#input' => TRUE,
@@ -556,7 +555,6 @@ function text_element_info() {
     '#delta' => 0,
     '#process' => array('text_textarea_with_summary_process'),
     '#theme_wrappers' => array('text_textarea'),
-    '#filter_value' => filter_default_format(),
   );
   return $types;
 }
@@ -657,9 +655,10 @@ function text_textfield_elements_process
   $element[$field_key]['#maxlength'] = !empty($field['settings']['max_length']) ? $field['settings']['max_length'] : NULL;
 
   if (!empty($instance['settings']['text_processing'])) {
-    $filter_key  = (count($element['#columns']) == 2) ? $element['#columns'][1] : 'format';
-    $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : filter_default_format();
-    $element[$field_key]['#text_format'] = $format;
+    $filter_key = (count($element['#columns']) == 2) ? $element['#columns'][1] : 'format';
+    $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : filter_format_default();
+    $element[$field_key]['#type'] .= '_format';
+    $element[$field_key]['#format'] = $format;
   }
 
   return $element;
@@ -691,8 +690,9 @@ function text_textarea_elements_process(
 
   if (!empty($instance['settings']['text_processing'])) {
     $filter_key = (count($element['#columns']) == 2) ? $element['#columns'][1] : 'format';
-    $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : filter_default_format();
-    $element[$field_key]['#text_format'] = $format;
+    $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : filter_format_default();
+    $element[$field_key]['#type'] .= '_format';
+    $element[$field_key]['#format'] = $format;
   }
 
   return $element;
@@ -722,7 +722,6 @@ function text_textarea_with_summary_proc
     '#title' => t('Summary'),
     '#description' => t('Leave blank to use trimmed value of full text as the summary.'),
     '#required' => $element['#required'],
-    '#display' => $display,
     '#attached' => array('js' => array(drupal_get_path('module', 'text') . '/text.js')),
     '#attributes' => array('class' => array('text-textarea-summary')),
     '#prefix' => '<div class="text-summary-wrapper">',
@@ -737,7 +736,6 @@ function text_textarea_with_summary_proc
     '#weight' => 1,
     '#title' => $display ? t('Full text') : $element['#title'],
     '#description' => $element['#description'],
-    '#required' => $element['#required'],
     '#required' => $instance['required'],
     '#attributes' => array('class' => array('text-full-textarea')),
     '#prefix' => '<div class="text-full-wrapper">',
@@ -746,8 +744,9 @@ function text_textarea_with_summary_proc
 
   if (!empty($instance['settings']['text_processing'])) {
     $filter_key  = (count($element['#columns']) == 2) ? $element['#columns'][1] : 'format';
-    $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : filter_default_format();
-    $element[$field_key]['#text_format'] = $format;
+    $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : filter_format_default();
+    $element[$field_key]['#type'] .= '_format';
+    $element[$field_key]['#format'] = $format;
   }
 
   return $element;
@@ -756,8 +755,10 @@ function text_textarea_with_summary_proc
 /**
  * Helper function to determine the value for a formatted text widget.
  *
- * '#text_format' puts the format in '[column 0]_format' in incoming values,
+ * The format is put into '[column 0]_format' in incoming values,
  * while we need it in '[column 1]'.
+ *
+ * @todo Most probably obsolete.
  */
 function text_field_widget_formatted_text_value($form, $edit = FALSE) {
   if ($edit !== FALSE) {
@@ -767,7 +768,7 @@ function text_field_widget_formatted_tex
     // The format selector uses #access = FALSE if only one format is
     // available. In this case, we don't receive its value, and need to
     // manually set it.
-    $edit['format'] = !empty($edit[$default_key]) ? $edit[$default_key] : filter_default_format();
+    $edit['format'] = !empty($edit[$default_key]) ? $edit[$default_key] : filter_format_default();
     unset($edit[$default_key]);
     return $edit;
   }
Index: modules/filter/filter.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v
retrieving revision 1.298
diff -u -p -r1.298 filter.module
--- modules/filter/filter.module	16 Oct 2009 19:06:23 -0000	1.298
+++ modules/filter/filter.module	18 Oct 2009 05:14:54 -0000
@@ -49,16 +49,49 @@ function filter_theme() {
       'arguments' => array('tips' => NULL, 'long' => FALSE),
       'file' => 'filter.pages.inc',
     ),
+    'filter_format_wrapper' => array(
+      'arguments' => array('element' => array()),
+    ),
     'filter_tips_more_info' => array(
       'arguments' => array(),
     ),
     'filter_guidelines' => array(
-      'arguments' => array('format' => NULL),
+      // @see http://drupal.org/node/600974
+      'arguments' => array('format' => NULL, 'dummy' => NULL),
     ),
   );
 }
 
 /**
+ * Implement of hook_elements().
+ *
+ * Elements defined by Filter module are wrappers around the respective,
+ * non-prefixed elements, extended by additionally required properties for
+ * filter_process_format().
+ *
+ * @see filter_process_format()
+ */
+function filter_element_info() {
+  $type['textfield_format'] = array(
+    '#input' => TRUE,
+    '#size' => 60,
+    '#maxlength' => 128,
+    '#autocomplete_path' => FALSE,
+    '#process' => array('filter_process_format'),
+    '#format' => filter_format_default(),
+  );
+  $type['textarea_format'] = array(
+    '#input' => TRUE,
+    '#cols' => 60,
+    '#rows' => 5,
+    '#resizable' => TRUE,
+    '#process' => array('filter_process_format'),
+    '#format' => filter_format_default(),
+  );
+  return $type;
+}
+
+/**
  * Implement hook_menu().
  */
 function filter_menu() {
@@ -428,7 +461,7 @@ function filter_get_formats_by_role($rid
  *
  * @see filter_fallback_format()
  */
-function filter_default_format($account = NULL) {
+function filter_format_default($account = NULL) {
   global $user;
   if (!isset($account)) {
     $account = $user;
@@ -617,65 +650,157 @@ function check_markup($text, $format_id 
 /**
  * Generate a selector for choosing a format in a form.
  *
- * @ingroup forms
- * @param $selected_format
- *   The ID of the format that is currently selected.
- * @param $weight
- *   The weight of the text format.
- * @param $parents
- *   Required when defining multiple text formats on a single node or having a different parent than 'format'.
+ * The form element will be expanded into two separate form elements, one
+ * holding the content of the element, and the other holding the text format
+ * selector. The original element is shifted into a child element, but is
+ * otherwise unaltered, so that the format selector is at the same level as the
+ * text field which it affects.
+ *
+ * The optional #format property should be the ID of an text format, found in
+ * {filter_format}.format. By default, FILTER_FORMAT_DEFAULT is used.
+ *
+ * For example:
+ * @code
+ *   // A simple textarea, such as a node body.
+ *   $form['body'] = array(
+ *     '#type' => 'textarea_format',
+ *     '#title' => t('Body'),
+ *     '#format' => isset($node->format) ? $node->format : filter_format_default(),
+ *   );
+ * @endcode
+ *
+ * Becomes:
+ * @code
+ *   $form['body'] = array(
+ *     // Type switches to 'markup', as we're only interested in submitting the child elements.
+ *     '#type' => 'markup',
+ *     // 'value' holds the original element.
+ *     'value' => array(
+ *       '#type' => 'textarea',
+ *       '#title' => t('Body'),
+ *       '#parents' => array('body'),
+ *     ),
+ *     // 'format' holds the text format selector.
+ *     'format' => array(
+ *       '#parents' => array('body_format'),
+ *       ...
+ *     ),
+ *   );
+ * @endcode
+ *
+ * And would result in:
+ * @code
+ *   // Original, unaltered form element value.
+ *   $form_state['values']['body'] = 'Example content';
+ *   // Chosen text format.
+ *   $form_state['values']['body_format'] = 1;
+ * @endcode
+ *
+ * @param $element
+ *   The form element to process.
+ *
  * @return
- *   HTML for the form element.
+ *   The expanded element.
  */
-function filter_form($selected_format = NULL, $weight = NULL, $parents = array('format')) {
+function filter_process_format($element) {
   global $user;
 
+  // Determine the form element parents and element name to use for the text
+  // format widget.
+  $parents = $element['#parents'];
+  $parents[] = 'format';
+
+  // Inject the real form element widget.
+  // We need to break references, otherwise form_builder() recurses infinitely.
+  $type = strtr($element['#type'], array('_format' => ''));
+  $element['value'] = (array) $element;
+  $element['value']['#type'] = $type;
+  $element['value'] += element_info($type);
+  $element['value']['#parents'][] = 'value';
+  // The form element's description is handled in theme_text_format_wrapper().
+  unset($element['value']['#description']);
+  // Clear the #process from the new child to prevent infinite recursion.
+  unset($element['value']['#process'][array_search('filter_process_format', $element['value']['#process'])]);
+  // Reset the element's weight, as we are rendering on a different layer.
+  $element['value']['#weight'] = 0;
+  // Reset conflicting properties.
+  unset($element['value']['#prefix']);
+  unset($element['value']['#suffix']);
+
   // Use the default format for this user if none was selected.
-  if (empty($selected_format)) {
-    $selected_format = filter_default_format($user);
+  if (empty($element['#format'])) {
+    $element['#format'] = filter_format_default($user);
   }
 
-  // Get a list of formats that the current user has access to.
-  $formats = filter_formats($user);
-
-  drupal_add_js('misc/form.js');
-  drupal_add_css(drupal_get_path('module', 'filter') . '/filter.css');
   $element_id = drupal_html_id('edit-' . implode('-', $parents));
 
-  $form = array(
-    '#type' => 'fieldset',
-    '#weight' => $weight,
-    '#attributes' => array('class' => array('filter-wrapper')),
+  // Turn the original element into text format wrapper.
+  $element['format']['#type'] = 'fieldset';
+  unset($element['format']['#theme']);
+  $element['#theme_wrappers'] = array('filter_format_wrapper');
+  $element['format']['#attributes'] = array('class' => array('filter-wrapper'));
+  $element['format']['#attached'] = array(
+    'js' => array('misc/form.js'),
+    'css' => array(drupal_get_path('module', 'filter') . '/filter.css'),
   );
-  $form['format_guidelines'] = array(
+  $element['format']['format_guidelines'] = array(
     '#prefix' => '<div id="' . $element_id . '-guidelines" class="filter-guidelines">',
     '#suffix' => '</div>',
-    '#weight' => 2,
+    '#weight' => 20,
   );
+  // Get a list of formats that the current user has access to.
+  $formats = filter_formats($user);
   foreach ($formats as $format) {
     $options[$format->format] = $format->name;
-    $form['format_guidelines'][$format->format] = array(
-      '#markup' => theme('filter_guidelines', array('format' => $format)),
+    $element['format']['format_guidelines'][$format->format] = array(
+      '#theme' => 'filter_guidelines',
+      '#format' => $format,
     );
   }
-  $form['format'] = array(
+  $element['format']['format'] = array(
     '#type' => 'select',
     '#title' => t('Text format'),
     '#options' => $options,
-    '#default_value' => $selected_format,
+    '#default_value' => $element['#format'],
     '#parents' => $parents,
     '#access' => count($formats) > 1,
     '#id' => $element_id,
+    '#weight' => 10,
     '#attributes' => array('class' => array('filter-list')),
   );
-  $form['format_help'] = array(
+  $element['format']['format_help'] = array(
     '#prefix' => '<div id="' . $element_id . '-help" class="filter-help">',
-    '#markup' => theme('filter_tips_more_info'),
+    '#theme' => 'filter_tips_more_info',
     '#suffix' => '</div>',
-    '#weight' => 1,
+    '#weight' => 0,
   );
 
-  return $form;
+  return $element;
+}
+
+/**
+ * Theme a text format form element.
+ *
+ * @param $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties of the element.
+ *     Properties used: #children, #description
+ *
+ * @return
+ *   A string representing the form element.
+ *
+ * @ingroup themeable
+ */
+function theme_filter_format_wrapper($variables) {
+  $element = $variables['element'];
+  $output = '<div class="text-format-wrapper">';
+  $output .= $element['#children'];
+  if (!empty($element['#description'])) {
+    $output .= '<div class="description">' . $element['#description'] . '</div>';
+  }
+  $output .= "</div>\n";
+
+  return $output;
 }
 
 /**
Index: modules/filter/filter.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.test,v
retrieving revision 1.46
diff -u -p -r1.46 filter.test
--- modules/filter/filter.test	13 Oct 2009 15:39:41 -0000	1.46
+++ modules/filter/filter.test	18 Oct 2009 03:32:57 -0000
@@ -496,8 +496,8 @@ class FilterDefaultFormatTestCase extend
 
     // Check that each user's default format is the lowest weighted format that
     // the user has access to.
-    $this->assertEqual(filter_default_format($first_user), $first_format->format, t("The first user's default format is the lowest weighted format that the user has access to."));
-    $this->assertEqual(filter_default_format($second_user), $second_format->format, t("The second user's default format is the lowest weighted format that the user has access to, and is different than the first user's."));
+    $this->assertEqual(filter_format_default($first_user), $first_format->format, t("The first user's default format is the lowest weighted format that the user has access to."));
+    $this->assertEqual(filter_format_default($second_user), $second_format->format, t("The second user's default format is the lowest weighted format that the user has access to, and is different than the first user's."));
 
     // Reorder the two formats, and check that both users now have the same
     // default.
@@ -505,7 +505,7 @@ class FilterDefaultFormatTestCase extend
     $edit['formats[' . $second_format->format . '][weight]'] = $minimum_weight - 3;
     $this->drupalPost('admin/config/content/formats', $edit, t('Save changes'));
     $this->resetFilterCaches();
-    $this->assertEqual(filter_default_format($first_user), filter_default_format($second_user), t('After the formats are reordered, both users have the same default format.'));
+    $this->assertEqual(filter_format_default($first_user), filter_format_default($second_user), t('After the formats are reordered, both users have the same default format.'));
   }
 
   /**
Index: modules/profile/profile.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/profile/profile.module,v
retrieving revision 1.279
diff -u -p -r1.279 profile.module
--- modules/profile/profile.module	10 Oct 2009 21:39:03 -0000	1.279
+++ modules/profile/profile.module	18 Oct 2009 03:33:16 -0000
@@ -280,7 +280,7 @@ function profile_view_field($account, $f
   if (isset($account->{$field->name}) && $value = $account->{$field->name}) {
     switch ($field->type) {
       case 'textarea':
-        return check_markup($value, filter_default_format($account), '', TRUE);
+        return check_markup($value, filter_format_default($account), '', TRUE);
       case 'textfield':
       case 'selection':
         return $browse ? l($value, 'profile/' . $field->name . '/' . $value) : check_plain($value);
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.163
diff -u -p -r1.163 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	16 Oct 2009 15:52:33 -0000	1.163
+++ modules/simpletest/drupal_web_test_case.php	18 Oct 2009 03:33:21 -0000
@@ -728,7 +728,7 @@ class DrupalWebTestCase extends DrupalTe
     // Merge body field value and format separately.
     $body = array(
       'value' => $this->randomName(32),
-      'format' => filter_default_format(),
+      'format' => filter_format_default(),
     );
     $langcode = !empty($settings['language']) ? $settings['language'] : FIELD_LANGUAGE_NONE;
     $settings['body'][$langcode][0] += $body;
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.820
diff -u -p -r1.820 system.module
--- modules/system/system.module	17 Oct 2009 05:50:29 -0000	1.820
+++ modules/system/system.module	18 Oct 2009 01:32:55 -0000
@@ -367,7 +367,7 @@ function system_element_info() {
     '#size' => 60,
     '#maxlength' => 128,
     '#autocomplete_path' => FALSE,
-    '#process' => array('form_process_text_format', 'ajax_process_form'),
+    '#process' => array('ajax_process_form'),
     '#theme' => 'textfield',
     '#theme_wrappers' => array('form_element'),
   );
@@ -389,7 +389,7 @@ function system_element_info() {
     '#cols' => 60,
     '#rows' => 5,
     '#resizable' => TRUE,
-    '#process' => array('form_process_text_format', 'ajax_process_form'),
+    '#process' => array('ajax_process_form'),
     '#theme' => 'textarea',
     '#theme_wrappers' => array('form_element'),
   );
