Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.911
diff -u -r1.911 system.module
--- modules/system/system.module	27 Mar 2010 05:52:50 -0000	1.911
+++ modules/system/system.module	28 Mar 2010 04:34:50 -0000
@@ -347,7 +347,7 @@
     '#size' => 60,
     '#maxlength' => 128,
     '#autocomplete_path' => FALSE,
-    '#process' => array('ajax_process_form'),
+    '#process' => array('ajax_process_form','form_process_autocomplete'),
     '#theme' => 'textfield',
     '#theme_wrappers' => array('form_element'),
   );
@@ -369,7 +369,7 @@
     '#cols' => 60,
     '#rows' => 5,
     '#resizable' => TRUE,
-    '#process' => array('ajax_process_form'),
+    '#process' => array('ajax_process_form', 'form_process_autocomplete'),
     '#theme' => 'textarea',
     '#theme_wrappers' => array('form_element'),
   );
Index: modules/system/system-behavior.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system-behavior.css,v
retrieving revision 1.6
diff -u -r1.6 system-behavior.css
--- modules/system/system-behavior.css	9 Mar 2010 11:45:37 -0000	1.6
+++ modules/system/system-behavior.css	28 Mar 2010 04:34:49 -0000
@@ -21,6 +21,8 @@
   color: #000;
   white-space: pre;
   cursor: default;
+  margin: 0;
+  list-style: none;
 }
 #autocomplete li.selected {
   background: #0072b9;
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.445
diff -u -r1.445 form.inc
--- includes/form.inc	26 Mar 2010 18:58:12 -0000	1.445
+++ includes/form.inc	28 Mar 2010 04:34:49 -0000
@@ -2807,6 +2807,35 @@
 }
 
 /**
+ * Add autocomplete to an element.
+ * 
+ * @param $element
+ *   An associative array containing the properties of the element.
+ *   - Properties used: #autocomplete_path.
+ *
+ * @return
+ *   The element with the additional attributes attached.
+ */
+function form_process_autocomplete($element) {
+  if (!empty($element['#autocomplete_path']) && drupal_valid_path($element['#autocomplete_path'])) {
+    $autocomplete_uri = check_url(url($element['#autocomplete_path'], array('absolute' => TRUE)));
+    $element['#attached']['js'][] = 'misc/autocomplete.js';
+    $element['#attached']['js'][] = array(
+      'data' => array(
+        'autocomplete' => array(
+          $autocomplete_uri => array(
+            'Drupal.ACDB' => array('#' . $element['#id']),
+          ),
+        ),
+      ),
+      'type' => 'setting',
+    );
+   $element['#attributes']['class'][] = 'form-autocomplete';
+  }
+  return $element;
+}
+
+/**
  * Theme a textfield form element.
  *
  * @param $variables
@@ -2828,11 +2857,6 @@
   $extra = '';
   $output = '';
 
-  if ($element['#autocomplete_path'] && drupal_valid_path($element['#autocomplete_path'])) {
-    drupal_add_js('misc/autocomplete.js');
-    $class[] = 'form-autocomplete';
-    $extra =  '<input class="autocomplete" type="hidden" id="' . $element['#id'] . '-autocomplete" value="' . check_url(url($element['#autocomplete_path'], array('absolute' => TRUE))) . '" disabled="disabled" />';
-  }
   _form_set_class($element, $class);
 
   $output .= '<input type="text"' . $maxlength . ' name="' . $element['#name'] . '" id="' . $element['#id'] . '"' . $size . ' value="' . check_plain($element['#value']) . '"' . drupal_attributes($element['#attributes']) . ' />';
Index: misc/autocomplete.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/autocomplete.js,v
retrieving revision 1.35
diff -u -r1.35 autocomplete.js
--- misc/autocomplete.js	29 Jan 2010 22:40:41 -0000	1.35
+++ misc/autocomplete.js	28 Mar 2010 04:34:49 -0000
@@ -6,17 +6,19 @@
  */
 Drupal.behaviors.autocomplete = {
   attach: function (context, settings) {
-    var acdb = [];
-    $('input.autocomplete', context).once('autocomplete', function () {
-      var uri = this.value;
-      if (!acdb[uri]) {
-        acdb[uri] = new Drupal.ACDB(uri);
+    if (settings.autocomplete) {
+      for (var uri in settings.autocomplete) {
+        for (var type in settings.autocomplete[uri]) {
+          var acdb = eval('new ' + type + '(uri)');
+          for (var i = 0; i < settings.autocomplete[uri][type].length; i++) {
+            $(settings.autocomplete[uri][type][i]).attr('autocomplete', 'OFF').once('autocomplete', function () {
+              $(this.form).submit(Drupal.autocompleteSubmit);
+              new Drupal.jsAC(this, acdb);
+            });
+          }
+        }
       }
-      var input = $('#' + this.id.substr(0, this.id.length - 13))
-        .attr('autocomplete', 'OFF')[0];
-      $(input.form).submit(Drupal.autocompleteSubmit);
-      new Drupal.jsAC(input, acdb[uri]);
-    });
+    }
   }
 };
 
@@ -34,14 +36,15 @@
  * An AutoComplete object.
  */
 Drupal.jsAC = function (input, db) {
-  var ac = this;
   this.input = input;
   this.db = db;
+  this.db.ac = this;
+  var ac = this;
 
   $(this.input)
     .keydown(function (event) { return ac.onkeydown(this, event); })
     .keyup(function (event) { ac.onkeyup(this, event); })
-    .blur(function () { ac.hidePopup(); ac.db.cancel(); });
+    .blur(function () { ac.db.cancel(); });
 
 };
 
@@ -262,8 +265,8 @@
   }
 
   // See if this key has been searched for before.
-  if (this.cache[searchString]) {
-    return this.owner.found(this.cache[searchString]);
+  if (this.cache['acdb_' + searchString]) {
+    return this.owner.found(this.cache['acdb_' + searchString]);
   }
 
   // Initiate delayed search.
@@ -280,7 +283,7 @@
       dataType: 'json',
       success: function (matches) {
         if (typeof matches.status == 'undefined' || matches.status != 0) {
-          db.cache[searchString] = matches;
+          db.cache['acdb_' + searchString] = matches;
           // Verify if these are still the matches the user wants to see.
           if (db.searchString == searchString) {
             db.owner.found(matches);
@@ -299,6 +302,7 @@
  * Cancels the current autocomplete request.
  */
 Drupal.ACDB.prototype.cancel = function () {
+  this.ac.hidePopup();
   if (this.owner) this.owner.setStatus('cancel');
   if (this.timer) clearTimeout(this.timer);
   this.searchString = '';
Index: modules/profile/profile.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/profile/profile.test,v
retrieving revision 1.24
diff -u -r1.24 profile.test
--- modules/profile/profile.test	8 Mar 2010 15:46:58 -0000	1.24
+++ modules/profile/profile.test	28 Mar 2010 04:34:49 -0000
@@ -334,15 +334,11 @@
     $field['value'] = $this->randomName();
     $this->setProfileField($field, $field['value']);
 
-    // Set some html for what we want to see in the page output later.
-    $autocomplete_html = '<input class="autocomplete" type="hidden" id="' . drupal_html_id('edit-' . $field['form_name'] . '-autocomplete') . '" value="' . url('profile/autocomplete/' . $field['fid'], array('absolute' => TRUE)) . '" disabled="disabled" />';
-    $field_html = '<input type="text" maxlength="255" name="' . $field['form_name'] . '" id="' . drupal_html_id('edit-' . $field['form_name']) . '" size="60" value="' . $field['value'] . '" class="form-text form-autocomplete required" />';
-
     // Check that autocompletion html is found on the user's profile edit page.
     $this->drupalGet('user/' . $this->admin_user->uid . '/edit/' . $category);
-    $this->assertRaw($autocomplete_html, t('Autocomplete found.'));
+    $this->assertRaw('"Drupal.ACDB":[', t('Autocomplete found.'));
     $this->assertRaw('misc/autocomplete.js', t('Autocomplete JavaScript found.'));
-    $this->assertRaw('class="form-text form-autocomplete"', t('Autocomplete form element class found.'));
+    $this->assertRaw('form-autocomplete', t('Autocomplete form element class found.'));
 
     // Check the autocompletion path using the first letter of our user's profile
     // field value to make sure access is allowed and a valid result if found.
@@ -356,7 +352,7 @@
 
     // Check that autocompletion html is not found on the user's profile edit page.
     $this->drupalGet('user/' . $this->normal_user->uid . '/edit/' . $category);
-    $this->assertNoRaw($autocomplete_html, t('Autocomplete not found.'));
+    $this->assertNoRaw('"Drupal.ACDB":[', t('Autocomplete not found.'));
 
     // User should be denied access to the profile autocomplete path.
     $this->drupalGet('profile/autocomplete/' . $field['fid'] . '/' . $field['value'][0]);

