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 = '
' . "\n"; - - $output .= $element['#children'] . "\n"; - - if (!empty($element['#description'])) { - $output .= '
' . $element['#description'] . "
\n"; - } - - $output .= "
\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 01:33:46 -0000 @@ -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_default_format(), '#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 01:33:56 -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_default_format(), '#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 01:43:35 -0000 @@ -659,7 +659,8 @@ function text_textfield_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; + $element[$field_key]['#type'] .= '_format'; + $element[$field_key]['#format'] = $format; } return $element; @@ -692,7 +693,8 @@ 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; + $element[$field_key]['#type'] .= '_format'; + $element[$field_key]['#format'] = $format; } return $element; @@ -747,7 +749,8 @@ 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; + $element[$field_key]['#type'] .= '_format'; + $element[$field_key]['#format'] = $format; } return $element; @@ -756,8 +759,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) { 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 01:56:03 -0000 @@ -59,6 +59,35 @@ function filter_theme() { } /** + * 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_elements() { + $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() { @@ -617,22 +646,93 @@ 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. + * 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_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 + * * @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'. + * * @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. + if (isset($element['#format_parents'])) { + // @todo Do we still need this? + $parents = $element['#format_parents']; + } + else { + $parents = $element['#parents']; + $parents[] = 'format'; + } + + // Inject the real form element widget, f.e. a textarea. + // We need to break references, otherwise form_builder() recurses infinitely. + $type = str_replace('_format', '', $element['value']['#type']); + $element['value'] = (array) $element; + $element['value'] += element_info($type); + $element['value']['#type'] = $type; + $element['value']['#parents'][] = 'value'; + // The form element's description is handled in theme_text_format_wrapper(). + unset($element['value']['#description']); + // We need to clear the #process from the new child, otherwise we would run + // into an infinite loop. + unset($element['value']['#process'][array_search('filter_process_format', $element['value']['#process'])]); + + // Make the stub element output the text format wrapper instead. + $element['#type'] = 'markup'; +// $element['#theme'] = NULL; + $element['#theme_wrappers'] = array('text_format_wrapper'); + // 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_default_format($user); } // Get a list of formats that the current user has access to. @@ -644,8 +744,10 @@ function filter_form($selected_format = $form = array( '#type' => 'fieldset', - '#weight' => $weight, + '#weight' => isset($element['#weight']) ? $element['#weight'] : NULL, '#attributes' => array('class' => array('filter-wrapper')), + '#attached_js' => array('misc/form.js'), + '#attached_css' => array(drupal_get_path('module', 'filter') . '/filter.css'), ); $form['format_guidelines'] = array( '#prefix' => '
', @@ -675,7 +777,33 @@ function filter_form($selected_format = '#weight' => 1, ); - return $form; + $element['format'] = $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_text_format_wrapper($variables) { + $element = $variables['element']; + $output = '
' . $element['#children']; + if (!empty($element['#description'])) { + $output .= '
' . $element['#description'] . '
'; + } + $output .= "
\n"; + + return $output; } /** 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'), );