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 = ''; - } _form_set_class($element, $class); $output .= ''; 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 = ''; - $field_html = ''; - // 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]);