Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1091
diff -u -p -r1.1091 common.inc
--- includes/common.inc	18 Jan 2010 03:28:13 -0000	1.1091
+++ includes/common.inc	19 Jan 2010 20:50:58 -0000
@@ -3567,11 +3567,15 @@ function drupal_clean_css_identifier($id
  *
  * @param $class
  *   The class name to clean.
+ * @param $underscores_only
+ *   If $class is known to only contain ASCII characters in the set 'a-z0-9_'
+ *   (i.e., lowercase letters, numbers, and underscore), then setting this to
+ *   TRUE results in faster execution.
  * @return
  *   The cleaned class name.
  */
-function drupal_html_class($class) {
-  return drupal_clean_css_identifier(drupal_strtolower($class));
+function drupal_html_class($class, $underscores_only = FALSE) {
+  return $underscores_only ? strtr($class, '_', '-') : drupal_clean_css_identifier(drupal_strtolower($class));
 }
 
 /**
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.569
diff -u -p -r1.569 theme.inc
--- includes/theme.inc	13 Jan 2010 05:40:03 -0000	1.569
+++ includes/theme.inc	19 Jan 2010 20:50:59 -0000
@@ -309,10 +309,6 @@ function drupal_theme_rebuild() {
  *     in hook_theme(). If there is more than one implementation and
  *     'render element' is not specified in a later one, then the previous
  *     definition is kept.
- *   - 'theme paths': The paths where implementations of a theme hook can be
- *     found. Its definition is similarly inherited like 'variables'. Each time
- *     _theme_process_registry() is called for this theme hook, either the
- *     'path' key from hook_theme() (if defined) or $path is added.
  *   - 'preprocess functions': See theme() for detailed documentation.
  *   - 'process functions': See theme() for detailed documentation.
  * @param $name
@@ -389,14 +385,6 @@ function _theme_process_registry(&$cache
         if (!isset($info['path'])) {
           $result[$hook]['template'] = $path . '/' . $info['template'];
         }
-
-        // These are used for template naming suggestions. Theme implementations
-        // can occur in multiple paths. Suggestions should follow.
-        if (!isset($info['theme paths']) && isset($cache[$hook])) {
-          $result[$hook]['theme paths'] = $cache[$hook]['theme paths'];
-        }
-        // Check for sub-directories.
-        $result[$hook]['theme paths'][] = isset($info['path']) ? $info['path'] : $path;
       }
 
       // Allow variable processors for all theming hooks, whether the hook is
@@ -861,17 +849,15 @@ function theme($hook, $variables = array
     // - The 'theme_hook_suggestions' variable is checked in FILO order, so the
     //   last suggestion added to the array takes precedence over suggestions
     //   added earlier.
-    $suggestions = array();
-    if (!empty($variables['theme_hook_suggestions'])) {
-      $suggestions = $variables['theme_hook_suggestions'];
-    }
-    if (!empty($variables['theme_hook_suggestion'])) {
-      $suggestions[] = $variables['theme_hook_suggestion'];
-    }
-    foreach (array_reverse($suggestions) as $suggestion) {
-      if (isset($hooks[$suggestion])) {
-        $info = $hooks[$suggestion];
-        break;
+    if (isset($variables['theme_hook_suggestion']) && isset($hooks[$variables['theme_hook_suggestion']])) {
+      $info = $hooks[$variables['theme_hook_suggestion']];
+    }
+    else {
+      foreach (array_reverse($variables['theme_hook_suggestions']) as $suggestion) {
+        if (isset($hooks[$suggestion])) {
+          $info = $hooks[$suggestion];
+          break;
+        }
       }
     }
   }
@@ -2179,11 +2165,15 @@ function template_preprocess(&$variables
   $variables['zebra'] = ($count[$hook] % 2) ? 'odd' : 'even';
   $variables['id'] = $count[$hook]++;
 
-  // Tell all templates where they are located.
-  $variables['directory'] = path_to_theme();
+  // Tell all templates where they are located. Usually, path_to_theme() is
+  // prefered to accessing a global variable directly, but here, we're
+  // more interested in speed, and since this function is part of theme.inc,
+  // it doesn't add too much maintenance difficulty.
+  global $theme_path;
+  $variables['directory'] = $theme_path;
 
   // Initialize html class attribute for the current hook.
-  $variables['classes_array'] = array(drupal_html_class($hook));
+  $variables['classes_array'] = array(drupal_html_class($hook, TRUE));
 
   // Merge in variables that don't depend on hook and don't change during a
   // single page request.
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.837
diff -u -p -r1.837 comment.module
--- modules/comment/comment.module	14 Jan 2010 02:00:08 -0000	1.837
+++ modules/comment/comment.module	19 Jan 2010 20:51:00 -0000
@@ -891,33 +891,6 @@ function comment_build_content($comment,
   entity_prepare_view('comment', array($comment->cid => $comment));
   $comment->content += field_attach_view('comment', $comment, $view_mode);
 
-  // Prior to Drupal 7, the comment body was a simple text variable, but with
-  // Drupal 7, it has been upgraded to a field. However, using theme('field') to
-  // render the comment body results in a noticeable performance degradation for
-  // pages with many comments. By unsetting #theme, we avoid the overhead of
-  // theme('field') and instead settle for simply rendering the formatted field
-  // value that exists as a child element of the 'comment_body' render array,
-  // which results in equivalent markup and rendering speed as if the comment
-  // body had not been upgraded to a field. Modules that require the comment
-  // body to be rendered as a full field (and are willing to accept the
-  // corresponding performance impact) can restore #theme to 'field' within a
-  // hook_comment_view() or hook_comment_view_alter() implementation.
-  // @todo Bypassing theme('field') is not ideal, because:
-  //   - The field label is not displayed, even if its setting is to be
-  //     displayed.
-  //   - hook_preprocess_field() functions do not run, and therefore, attributes
-  //     added in those functions (for example, for RDF) are not output.
-  //   - The HTML markup that's within field.tpl.php is not output, so theme
-  //     developers must use different CSS rules for the comment body than for
-  //     all other fields.
-  //   The goal is for theme('field') to be sufficiently optimized prior to
-  //   Drupal 7 release, so that this code can be removed, and the comment body
-  //   can be rendered just like all other fields. Otherwise, another solution
-  //   to the above problems will be needed. @see http://drupal.org/node/659788.
-  if (isset($comment->content['comment_body']['#theme']) && ($comment->content['comment_body']['#theme'] === 'field')) {
-    unset($comment->content['comment_body']['#theme']);
-  }
-
   if (empty($comment->in_preview)) {
     $comment->content['links']['comment'] = array(
       '#theme' => 'links__comment',
@@ -2510,7 +2483,7 @@ function comment_rdf_mapping() {
       'type' => 'comment',
       'bundle' => RDF_DEFAULT_BUNDLE,
       'mapping' => array(
-        'rdftype' => array('sioc:Post'),
+        'rdftype' => array('sioc:Post', 'sioct:Comment'),
         'title' => array(
           'predicates' => array('dc:title'),
         ),
@@ -2524,7 +2497,7 @@ function comment_rdf_mapping() {
           'datatype' => 'xsd:dateTime',
           'callback' => 'date_iso8601',
         ),
-        'body' => array(
+        'comment_body' => array(
           'predicates' => array('content:encoded'),
         ),
         'pid' => array(
Index: modules/comment/comment.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.test,v
retrieving revision 1.63
diff -u -p -r1.63 comment.test
--- modules/comment/comment.test	11 Jan 2010 16:25:16 -0000	1.63
+++ modules/comment/comment.test	19 Jan 2010 20:51:00 -0000
@@ -1149,10 +1149,10 @@ class CommentRdfaTestCase extends Commen
     // Tests comment #2 as anonymous user.
     $this->_testBasicCommentRdfaMarkup($comment2, $anonymous_user);
     // Tests the RDFa markup for the homepage (specific to anonymous comments).
-    $comment_homepage = $this->xpath("//div[@typeof='sioc:Post']//span[@rel='sioc:has_creator']/a[contains(@class, 'username') and @typeof='sioc:User' and @property='foaf:name' and @href='http://example.org/' and contains(@rel, 'foaf:page')]");
+    $comment_homepage = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//span[@rel='sioc:has_creator']/a[contains(@class, 'username') and @typeof='sioc:User' and @property='foaf:name' and @href='http://example.org/' and contains(@rel, 'foaf:page')]");
     $this->assertTrue(!empty($comment_homepage), t('RDFa markup for the homepage of anonymous user found.'));
     // There should be no about attribute on anonymous comments.
-    $comment_homepage = $this->xpath("//div[@typeof='sioc:Post']//span[@rel='sioc:has_creator']/a[@about]");
+    $comment_homepage = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//span[@rel='sioc:has_creator']/a[@about]");
     $this->assertTrue(empty($comment_homepage), t('No about attribute is present on anonymous user comment.'));
 
     // Tests comment #2 as logged in user.
@@ -1160,10 +1160,10 @@ class CommentRdfaTestCase extends Commen
     $this->drupalGet('node/' . $this->node2->nid);
     $this->_testBasicCommentRdfaMarkup($comment2, $anonymous_user);
     // Tests the RDFa markup for the homepage (specific to anonymous comments).
-    $comment_homepage = $this->xpath("//div[@typeof='sioc:Post']//span[@rel='sioc:has_creator']/a[contains(@class, 'username') and @typeof='sioc:User' and @property='foaf:name' and @href='http://example.org/' and contains(@rel, 'foaf:page')]");
+    $comment_homepage = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//span[@rel='sioc:has_creator']/a[contains(@class, 'username') and @typeof='sioc:User' and @property='foaf:name' and @href='http://example.org/' and contains(@rel, 'foaf:page')]");
     $this->assertTrue(!empty($comment_homepage), t('RDFa markup for the homepage of anonymous user found.'));
     // There should be no about attribute on anonymous comments.
-    $comment_homepage = $this->xpath("//div[@typeof='sioc:Post']//span[@rel='sioc:has_creator']/a[@about]");
+    $comment_homepage = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//span[@rel='sioc:has_creator']/a[@about]");
     $this->assertTrue(empty($comment_homepage), t('No about attribute is present on anonymous user comment.'));
   }
 
@@ -1174,19 +1174,21 @@ class CommentRdfaTestCase extends Commen
    *
    * @param $comment
    *   Comment object.
-   * @param $acount
+   * @param $account
    *   An array containing information about an anonymous user.
    */
   function _testBasicCommentRdfaMarkup($comment, $account = array()) {
-    $comment_container = $this->xpath("//div[contains(@class, 'comment') and @typeof='sioc:Post']");
-    $this->assertTrue(!empty($comment_container));
-    $comment_title = $this->xpath("//div[@typeof='sioc:Post']//h3[@property='dc:title']");
-    $this->assertEqual((string)$comment_title[0]->a, $comment->subject);
-    $comment_date = $this->xpath("//div[@typeof='sioc:Post']//*[contains(@property, 'dc:date') and contains(@property, 'dc:created')]");
-    $this->assertTrue(!empty($comment_date));
+    $comment_container = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]");
+    $this->assertTrue(!empty($comment_container), t('Comment RDF type for comment found.'));
+    $comment_title = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//h3[@property='dc:title']");
+    $this->assertEqual((string)$comment_title[0]->a, $comment->subject, t('RDFa markup for the comment title found.'));
+    $comment_date = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//*[contains(@property, 'dc:date') and contains(@property, 'dc:created')]");
+    $this->assertTrue(!empty($comment_date), t('RDFa markup for the date of the comment found.'));
     // The author tag can be either a or span
-    $comment_author = $this->xpath("//div[@typeof='sioc:Post']//span[@rel='sioc:has_creator']/*[contains(@class, 'username') and @typeof='sioc:User' and @property='foaf:name']");
+    $comment_author = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//span[@rel='sioc:has_creator']/*[contains(@class, 'username') and @typeof='sioc:User' and @property='foaf:name']");
     $name = empty($account['name']) ? $this->web_user->name : $account['name'] . ' (not verified)';
-    $this->assertEqual((string)$comment_author[0], $name);
+    $this->assertEqual((string)$comment_author[0], $name, t('RDFa markup for the comment author found.'));
+    $comment_body = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//div[@class='content']//div[contains(@class, 'comment-body')]//div[@property='content:encoded']");
+    $this->assertEqual((string)$comment_body[0]->p, $comment->comment, t('RDFa markup for the comment body found.'));
   }
 }
Index: modules/field/field.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.module,v
retrieving revision 1.61
diff -u -p -r1.61 field.module
--- modules/field/field.module	13 Jan 2010 05:40:03 -0000	1.61
+++ modules/field/field.module	19 Jan 2010 20:51:00 -0000
@@ -177,19 +177,14 @@ function field_help($path, $arg) {
  * Implements hook_theme().
  */
 function field_theme() {
-  $path = drupal_get_path('module', 'field') . '/theme';
-  $items = array(
+  return array(
     'field' => array(
-      'template' => 'field',
       'render element' => 'element',
-      'path' => $path,
     ),
     'field_multiple_value_form' => array(
       'render element' => 'element',
     ),
   );
-
-  return $items;
 }
 
 /**
@@ -741,69 +736,141 @@ function field_extract_bundle($obj_type,
 }
 
 /**
- * Theme preprocess function for field.tpl.php.
+ * Theme preprocess function for theme_field() and field.tpl.php.
  *
+ * @see theme_field()
  * @see field.tpl.php
  */
-function template_preprocess_field(&$variables) {
+function template_preprocess_field(&$variables, $hook) {
   $element = $variables['element'];
 
-  // @todo Convert to using drupal_html_class() after benchmarking the impact of
-  //   doing so.
-  $field_type_css = strtr($element['#field_type'], '_', '-');
-  $field_name_css = strtr($element['#field_name'], '_', '-');
-
-  // Prepare an $items variable that the template can simply loop on.
-  // Filter out non-children properties that might have been added if the
-  // renderable array has gone through form_builder().
-  $items = array_intersect_key($element, array_flip(element_children($element)));
+  // For faster performance, by default, the theme implementation is a function.
+  // However, it may be overridden by a template implementation, but even if it
+  // is, the non-hook-specific *_preprocess() and *_process() functions don't
+  // get called automatically. For both template and function implementations,
+  // this theme hook uses the variables provided by template_preprocess(), and
+  // since it's not called automatically, we call it here.
+  template_preprocess($variables, $hook);
+
+  // There's some overhead in calling check_plain() so only call it if the label
+  // variable is being displayed. Otherwise, set it to NULL to avoid PHP
+  // warnings if a theme implementation accesses the variable even when it's
+  // supposed to be hidden. If a theme implementation needs to print a hidden
+  // label, it needs to supply a preprocess function that sets it to the
+  // sanitized element title or whatever else is wanted in its place.
+  $variables['label_display'] = $element['#label_display'];
+  $variables['label_hidden'] = ($element['#label_display'] == 'hidden');
+  $variables['label'] = $variables['label_hidden'] ? NULL : check_plain($element['#title']);
+
+  // We want other preprocess functions and the theme implementation to have
+  // fast access to the field item render arrays. The vast majority of the time,
+  // the keys for the item render arrays are the same as the keys of #items,
+  // so an expensive call to element_children() can be avoided. If the keys of
+  // the item render arrays are different than the keys of #items, then the code
+  // responsible for making them different (for example, a complex
+  // hook_field_formatter_view() implementation) must set #use_element_children
+  // to ensure that the correct items are rendered.
+  $variables['items'] = array();
+  $variables['item_attributes_array'] = array();
+  $deltas = empty($element['#use_element_children']) ? array_keys($element['#items']) : element_children($element);
+  foreach ($deltas as $delta) {
+    if (!empty($element[$delta])) {
+      $variables['items'][$delta] = $element[$delta];
+      $variables['item_attributes_array'][$delta] = array();
+    }
+  }
+
+  // Add default CSS classes.
+  $variables['field_name_css'] = drupal_html_class($element['#field_name'], TRUE);
+  $variables['field_type_css'] = drupal_html_class($element['#field_type'], TRUE);
+  $variables['classes_array'] = array(
+    'field',
+    'field-name-' . $variables['field_name_css'],
+    'field-type-' . $variables['field_type_css'],
+    'field-label-' . $variables['label_display'],
+  );
+
+  // Add specific suggestions that can override the default implementation.
+  $variables['theme_hook_suggestions'] = array(
+    'field',
+    'field__' . $element['#field_name'],
+    'field__' . $element['#bundle'],
+    'field__' . $element['#field_name'] . '__' . $element['#bundle'],
+  );
 
-  $additions = array(
+  // Expose additional variables that may be useful to a custom implementation.
+  $variables += array(
     'object' => $element['#object'],
     'view_mode' => $element['#view_mode'],
-    'items' => $items,
     'field_type' => $element['#field_type'],
     'field_name' => $element['#field_name'],
-    'field_type_css' => $field_type_css,
-    'field_name_css' => $field_name_css,
-    'label' => check_plain($element['#title']),
-    'label_display' => $element['#label_display'],
-    'label_hidden' => $element['#label_display'] == 'hidden',
     'field_language' => $element['#language'],
     'field_translatable' => $element['#field_translatable'],
-    'classes_array' => array(
-      'field',
-      'field-name-' . $field_name_css,
-      'field-type-' . $field_type_css,
-      'field-label-' . $element['#label_display'],
-    ),
-    'theme_hook_suggestions' => array(
-      'field',
-      'field__' . $element['#field_name'],
-      'field__' . $element['#bundle'],
-      'field__' . $element['#field_name'] . '__' . $element['#bundle'],
-    ),
   );
-  $variables = array_merge($variables, $additions);
-
-  // Initialize attributes for each item.
-  $variables['item_attributes_array'] = array();
-  foreach ($variables['items'] as $delta => $item) {
-    $variables['item_attributes_array'][$delta] = array();
-  }
 }
 
 /**
- * Theme process function for field.tpl.php.
+ * Theme process function for theme_field() and field.tpl.php.
  *
+ * @see theme_field()
  * @see field.tpl.php
  */
-function template_process_field(&$variables) {
-  // Flatten out attributes for each item.
+function template_process_field(&$variables, $hook) {
+  // template_process() does not automatically run, but we want it to.
+  // @see template_preprocess_field()
+  template_process($variables, $hook);
+
+  // Flatten out attributes for each item. For best performance, only call
+  // drupal_attributes() when needed.
   foreach ($variables['items'] as $delta => $item) {
-    $variables['item_attributes'][$delta] = drupal_attributes($variables['item_attributes_array'][$delta]);
+    $variables['item_attributes'][$delta] = $variables['item_attributes_array'][$delta] ? drupal_attributes($variables['item_attributes_array'][$delta]) : '';
   }
 }
 /**
  * @} End of "defgroup field"
  */
+
+/**
+ * Returns a themed field.
+ *
+ * This is the default theme implementation to display the value of a field.
+ * There is a nearly equivalent template implementation, field.tpl.php, that
+ * can be copied to a theme's folder to override this default implementation,
+ * but like any theme function, this function can also be overridden by a
+ * THEMENAME_field() function within the theme's template.php file. This dual
+ * implementation and choice for whether to override with a function or a
+ * template exists to accomodate a diverse range of uses. Many people find it
+ * much easier to customize templates than override functions, so the option to
+ * override with a template implementation lowers the barrier to achieve the
+ * desired look for a website. But template implementations take longer to
+ * execute than function implementations, so overriding with a function instead
+ * of a template is recommended where the performance difference is signficant:
+ * high traffic websites that have pages containing many fields.
+ *
+ * @see template_preprocess_field()
+ * @see template_process_field()
+ * @see field.tpl.php
+ *
+ * @ingroup themeable
+ */
+function theme_field($variables) {
+  $output = '';
+
+  // Render the label, if it's not hidden.
+  if (!$variables['label_hidden']) {
+    $output .= '<div class="field-label"' . $variables['title_attributes'] . '>' . $variables['label'] . ':&nbsp;</div>';
+  }
+
+  // Render the items.
+  $output .= '<div class="field-items"' . $variables['content_attributes'] . '>';
+  foreach ($variables['items'] as $delta => $item) {
+    $class_string = ' class="field-item ' . ($delta % 2 ? 'odd' : 'even') . '"';
+    $output .= '<div' . $class_string . $variables['item_attributes'][$delta] . '>' . drupal_render($item) . '</div>';
+  }
+  $output .= '</div>';
+
+  // Render the top-level DIV.
+  $output = '<div class="' . $variables['classes'] . ' clearfix"' . $variables['attributes'] . '>' . $output . '</div>';  
+
+  return $output;
+}
Index: modules/field/theme/field.tpl.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/theme/field.tpl.php,v
retrieving revision 1.10
diff -u -p -r1.10 field.tpl.php
--- modules/field/theme/field.tpl.php	26 Dec 2009 16:50:08 -0000	1.10
+++ modules/field/theme/field.tpl.php	19 Jan 2010 20:51:00 -0000
@@ -3,7 +3,16 @@
 
 /**
  * @file field.tpl.php
- * Default theme implementation to display the value of a field.
+ * Default template implementation to display the value of a field.
+ *
+ * This default template is not used, because an equivalent implementation
+ * exists in the theme_field() function. Function implementations are faster
+ * than template implementations, and because on some sites, there can be many
+ * fields displayed on a page, the faster function implementation is used by
+ * default. People building sites without too many fields per page and who
+ * find it easier to customize templates than override functions can copy this
+ * file to the theme's folder and customize it, and the customized template will
+ * be used instead of the default function.
  *
  * Available variables:
  * - $items: An array of field values. Use render() to output them.
Index: modules/rdf/rdf.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/rdf/rdf.module,v
retrieving revision 1.20
diff -u -p -r1.20 rdf.module
--- modules/rdf/rdf.module	14 Jan 2010 06:31:45 -0000	1.20
+++ modules/rdf/rdf.module	19 Jan 2010 20:51:01 -0000
@@ -548,13 +548,6 @@ function rdf_preprocess_comment(&$variab
     $variables['title_attributes_array']['property'] = $comment->rdf_mapping['title']['predicates'];
     $variables['title_attributes_array']['datatype'] = '';
   }
-  if (!empty($comment->rdf_mapping['body'])) {
-    // We need a special case here since the comment body is not a field. Note
-    // that for that reason, fields attached to comment will be ignored by RDFa
-    // parsers since we set the property attribute here.
-    // @todo Use fields instead, see http://drupal.org/node/538164
-    $variables['content_attributes_array']['property'] = $comment->rdf_mapping['body']['predicates'];
-  }
 
   // Annotates the parent relationship between the current comment and the node
   // it belongs to. If available, the parent comment is also annotated.
Index: modules/system/system.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.api.php,v
retrieving revision 1.120
diff -u -p -r1.120 system.api.php
--- modules/system/system.api.php	13 Jan 2010 06:26:49 -0000	1.120
+++ modules/system/system.api.php	19 Jan 2010 20:51:02 -0000
@@ -1136,9 +1136,6 @@ function hook_theme($existing, $type, $t
  *    'file' => 'modules/user/user.pages.inc',
  *    'type' => 'module',
  *    'theme path' => 'modules/user',
- *    'theme paths' => array(
- *      0 => 'modules/user',
- *    ),
  *    'preprocess functions' => array(
  *      0 => 'template_preprocess',
  *      1 => 'template_preprocess_user_profile',
