? .DS_Store
? .swp
? cache_api_07.patch
? clear_cache_06.patch
? synonym_collapsing_00.patch
? synonym_collapsing_01.patch
? synonym_collapsing_02.patch
? tmp.diff
? vocabulary_checkboxes_00.patch
? vocabulary_checkboxes_01.patch
? vocabulary_checkboxes_02.patch
? modules/.DS_Store
? sites/.DS_Store
? sites/default/files
? sites/default/settings.php
Index: misc/autocomplete.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/autocomplete.js,v
retrieving revision 1.29
diff -u -p -r1.29 autocomplete.js
--- misc/autocomplete.js	27 Apr 2009 20:19:35 -0000	1.29
+++ misc/autocomplete.js	28 Jun 2009 09:20:31 -0000
@@ -255,6 +255,12 @@ Drupal.ACDB.prototype.search = function 
   var db = this;
   this.searchString = searchString;
 
+  // See if this string needs to be searched for anyway.
+  searchString = searchString.replace(/^\s+|\s+$/, '');
+  if (searchString.charAt(searchString.length - 1) == ',') {
+    return;
+  }
+
   // See if this key has been searched for before.
   if (this.cache[searchString]) {
     return this.owner.found(this.cache[searchString]);
Index: modules/taxonomy/taxonomy.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.admin.inc,v
retrieving revision 1.55
diff -u -p -r1.55 taxonomy.admin.inc
--- modules/taxonomy/taxonomy.admin.inc	20 Jun 2009 18:32:04 -0000	1.55
+++ modules/taxonomy/taxonomy.admin.inc	28 Jun 2009 09:20:34 -0000
@@ -754,7 +754,7 @@ function taxonomy_form_term(&$form_state
     '#type' => 'textarea',
     '#title' => t('Synonyms'),
     '#default_value' => implode("\n", taxonomy_get_synonyms($edit['tid'])),
-    '#description' => t('Synonyms of this term, one synonym per line.'));
+    '#description' => t('One synonym per line. Text input term selection widgets will show terms whose synonyms match the entered value as suggestions.'));
   $form['advanced']['weight'] = array(
     '#type' => 'textfield',
     '#title' => t('Weight'),
Index: modules/taxonomy/taxonomy.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.pages.inc,v
retrieving revision 1.29
diff -u -p -r1.29 taxonomy.pages.inc
--- modules/taxonomy/taxonomy.pages.inc	12 Jun 2009 13:59:56 -0000	1.29
+++ modules/taxonomy/taxonomy.pages.inc	28 Jun 2009 09:20:34 -0000
@@ -122,36 +122,52 @@ function taxonomy_term_edit($term) {
 /**
  * Helper function for autocompletion
  */
-function taxonomy_autocomplete($vid, $string = '') {
+function taxonomy_autocomplete($vid = 0, $tags_typed = '') {
   // The user enters a comma-separated list of tags. We only autocomplete the last tag.
-  $array = drupal_explode_tags($string);
+  $tags_typed = drupal_explode_tags($tags_typed);
+  $tag_last = drupal_strtolower(array_pop($tags_typed));
 
-  // Fetch last tag
-  $last_string = trim(array_pop($array));
   $matches = array();
-  if ($last_string != '') {
+  if ($tag_last != '') {
     $query = db_select('taxonomy_term_data', 't');
     $query->addTag('term_access');
-
-    $tags = $query
+    $query->leftJoin('taxonomy_term_synonym', 'ts', 't.tid = ts.tid');
+    // Don't select already entered terms.
+    if (count($tags_typed)) {
+      $query->condition('t.name', $tags_typed, 'NOT IN');
+    }
+    $tags_return = $query
       ->fields('t', array('tid', 'name'))
       ->condition('t.vid', $vid)
-      ->where("LOWER(t.name) LIKE LOWER(:last_string)", array(':last_string' => '%' . $last_string . '%'))
+      // Select rows that either match by term or synonym name.
+      ->condition(db_or()
+	    ->where("LOWER(t.name) LIKE :last_string", array(':last_string' => '%' . $tag_last . '%'))
+	    ->where("LOWER(ts.name) LIKE :last_string", array(':last_string' => '%' . $tag_last . '%'))
+      )
       ->range(0, 10)
       ->execute()
       ->fetchAllKeyed();
 
-    $prefix = count($array) ? implode(', ', $array) . ', ' : '';
+    $prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : '';
 
-    foreach ($tags as $tid => $name) {
+    // We use two arrays to make sure synonym suggestions appear last.
+    $term_matches = $synonym_matches = array();
+    foreach ($tags_return as $tid => $name) {
       $n = $name;
       // Commas and quotes in terms are special cases, so encode 'em.
       if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) {
         $n = '"' . str_replace('"', '""', $name) . '"';
       }
-      $matches[$prefix . $n] = check_plain($name);
+      // Inform the user his query matched a synonym rather than a term.
+      if (strpos(drupal_strtolower($name), $tag_last) === FALSE) {
+        $name = t('Did you mean %suggestion', array('%suggestion' => $name));
+        $synonym_matches[$prefix . $n] = filter_xss($name);
+      }
+      else {
+        $term_matches[$prefix . $n] = filter_xss($name);
+      }
     }
   }
 
-  drupal_json($matches);
+  drupal_json(array_merge($term_matches, $synonym_matches));
 }
