? .DS_Store
? autocomplete-exchangeableACDB.patch
? autocomplete-exchangeableACDB_4.patch
? includes/.DS_Store
? misc/.DS_Store
? modules/.DS_Store
? modules/system/.DS_Store
? sites/default/files
? sites/default/settings.php
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.426
diff -u -p -r1.426 form.inc
--- includes/form.inc	8 Jan 2010 06:36:34 -0000	1.426
+++ includes/form.inc	10 Jan 2010 00:15:49 -0000
@@ -2826,6 +2826,35 @@ function theme_hidden($variables) {
 }
 
 /**
+ * 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
@@ -2847,11 +2876,6 @@ function theme_textfield($variables) {
   $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);
 
   if (isset($element['#field_prefix'])) {
Index: misc/autocomplete.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/autocomplete.js,v
retrieving revision 1.34
diff -u -p -r1.34 autocomplete.js
--- misc/autocomplete.js	5 Sep 2009 12:03:31 -0000	1.34
+++ misc/autocomplete.js	10 Jan 2010 00:15: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 @@ Drupal.autocompleteSubmit = function () 
  * 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(); });
 
 };
 
@@ -299,6 +302,7 @@ Drupal.ACDB.prototype.search = function 
  * 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.23
diff -u -p -r1.23 profile.test
--- modules/profile/profile.test	20 Nov 2009 04:15:15 -0000	1.23
+++ modules/profile/profile.test	10 Jan 2010 00:15:49 -0000
@@ -334,15 +334,11 @@ class ProfileTestAutocomplete extends Pr
     $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 @@ class ProfileTestAutocomplete extends Pr
 
     // 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]);
Index: modules/system/system-behavior.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system-behavior.css,v
retrieving revision 1.1
diff -u -p -r1.1 system-behavior.css
--- modules/system/system-behavior.css	7 Jan 2010 07:41:46 -0000	1.1
+++ modules/system/system-behavior.css	10 Jan 2010 00:15:49 -0000
@@ -21,6 +21,8 @@
   color: #000;
   white-space: pre;
   cursor: default;
+  margin: 0;
+  list-style: none;
 }
 #autocomplete li.selected {
   background: #0072b9;
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.873
diff -u -p -r1.873 system.module
--- modules/system/system.module	10 Jan 2010 00:09:37 -0000	1.873
+++ modules/system/system.module	10 Jan 2010 00:15:49 -0000
@@ -353,7 +353,7 @@ function system_element_info() {
     '#size' => 60,
     '#maxlength' => 128,
     '#autocomplete_path' => FALSE,
-    '#process' => array('form_process_text_format', 'ajax_process_form'),
+    '#process' => array('form_process_text_format', 'ajax_process_form', 'form_process_autocomplete'),
     '#theme' => 'textfield',
     '#theme_wrappers' => array('form_element'),
   );
@@ -375,7 +375,7 @@ function system_element_info() {
     '#cols' => 60,
     '#rows' => 5,
     '#resizable' => TRUE,
-    '#process' => array('form_process_text_format', 'ajax_process_form'),
+    '#process' => array('form_process_text_format', 'ajax_process_form', 'form_process_autocomplete'),
     '#theme' => 'textarea',
     '#theme_wrappers' => array('form_element'),
   );
