diff --git a/core/core.libraries.yml b/core/core.libraries.yml index 7c388089f0..f90cc9ac52 100644 --- a/core/core.libraries.yml +++ b/core/core.libraries.yml @@ -105,7 +105,11 @@ drupal.announce: - core/drupal.debounce awesomplete: - version: VERSION + version: 1.1.5 + license: + name: MIT + url: https://github.com/LeaVerou/awesomplete/blob/gh-pages/LICENSE + gpl-compatible: true js: assets/vendor/awesomplete/awesomplete.js: {} css: @@ -479,6 +483,21 @@ jquery.ui.accordion: - core/jquery.ui - core/jquery.ui.widget +jquery.ui.autocomplete: + version: *jquery_ui_version + license: *jquery_ui_license + js: + assets/vendor/jquery.ui/ui/widgets/autocomplete-min.js: { minified: true } + css: + component: + assets/vendor/jquery.ui/themes/base/autocomplete.css: {} + dependencies: + - core/jquery.ui + - core/jquery.ui.widget + - core/jquery.ui.position + - core/jquery.ui.menu + deprecated: The "%library_id%" asset library is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. See https://www.drupal.org/project/drupal/issues/3076171 + jquery.ui.button: version: *jquery_ui_version license: *jquery_ui_license diff --git a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php index 2e2464cd29..9fb5330928 100644 --- a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php +++ b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php @@ -142,7 +142,7 @@ public static function processEntityAutocomplete(array &$element, FormStateInter 'selection_settings_key' => $selection_settings_key, ]; - // Create attribute that will be used for client side enforcement of field + // Create attribute that will be used for client-side enforcement of field // cardinality. $name = explode('[', $element['#name'])[0]; if (!empty($complete_form[$name]['widget']['#theme']) && $complete_form[$name]['widget']['#theme'] === 'field_multiple_value_form') { diff --git a/core/misc/autocomplete.es6.js b/core/misc/autocomplete.es6.js index 3cccc758e6..8c774d1e34 100644 --- a/core/misc/autocomplete.es6.js +++ b/core/misc/autocomplete.es6.js @@ -58,7 +58,7 @@ const extractLastTerm = terms => autocomplete.splitValues(terms).pop(); /** - * Detemines if a suggestion should be an available option. + * Determines if a suggestion should be an available option. * Does not use arrow syntax so there is access to Awesomplete's this object. * @param {object} suggestion * A suggestion based on user input. It is an object with label and value @@ -66,22 +66,25 @@ * @param {string} input * The text entered in the input field. * - * @return {bool} + * @return {boolean} * If the suggestion should be displayed in the results. */ function filterResults(suggestion, input) { const { options } = Drupal.autocomplete; const inputElement = this.input; - const cardinality = inputElement - .closest('[data-autocomplete-cardinality]') - .getAttribute('data-autocomplete-cardinality'); + const inputWrapper = inputElement.closest( + '[data-autocomplete-cardinality]', + ); + const cardinality = inputWrapper + ? inputWrapper.getAttribute('data-autocomplete-cardinality') + : -1; const suggestionValue = suggestion.value; const currentValues = autocomplete.splitValues(input); - const inputSpecificFirstCharBlacklist = inputElement.hasAttribute( - 'data-autocomplete-first-character-blacklist', + const inputSpecificFirstCharDenylist = inputElement.hasAttribute( + 'data-autocomplete-first-character-denylist', ) - ? inputElement.getAttribute('data-autocomplete-first-character-blacklist') + ? inputElement.getAttribute('data-autocomplete-first-character-denylist') : ''; // Prevent suggestions if the maximum number of items is reached. @@ -89,10 +92,10 @@ return false; } - // Prevent suggestions if the first input character is in the blacklist. + // Prevent suggestions if the first input character is in the denylist. if ( - options.firstCharacterBlacklist.indexOf(input[0]) !== -1 || - inputSpecificFirstCharBlacklist.indexOf(input[0]) !== -1 + options.firstCharacterDenylist.indexOf(input[0]) !== -1 || + inputSpecificFirstCharDenylist.indexOf(input[0]) !== -1 ) { return false; } @@ -194,7 +197,7 @@ }); // Add class previously added by jQueryUI for backwards compatibility. - autocompleteElement.classList.add('awesomplete-input'); + autocompleteElement.classList.add('ui-autocomplete-input'); // Change role to textbox, Awesomplete defaults to combobox. The // screenreader instructions for combobox assume select options are @@ -231,7 +234,7 @@ if (autocomplete.cache[inputId].hasOwnProperty(term)) { awesomplete.list = autocomplete.cache[inputId][term]; awesomplete.evaluate(); - readResults(autocomplete.cache[inputId][term].length); + readResults(awesomplete.ul.children.length); } else { const apiUrl = input.getAttribute('data-autocomplete-path'); const xhr = new XMLHttpRequest(); @@ -284,7 +287,7 @@ replace: replaceInputValue, sort: false, minChars: 1, - firstCharacterBlacklist: ',', + firstCharacterDenylist: ',', autoFirst: false, maxItems: 10, }, diff --git a/core/misc/autocomplete.js b/core/misc/autocomplete.js index a293da98fe..0fc61c10b8 100644 --- a/core/misc/autocomplete.js +++ b/core/misc/autocomplete.js @@ -43,17 +43,18 @@ var options = Drupal.autocomplete.options; var inputElement = this.input; - var cardinality = inputElement.closest('[data-autocomplete-cardinality]').getAttribute('data-autocomplete-cardinality'); + var inputWrapper = inputElement.closest('[data-autocomplete-cardinality]'); + var cardinality = inputWrapper ? inputWrapper.getAttribute('data-autocomplete-cardinality') : -1; var suggestionValue = suggestion.value; var currentValues = autocomplete.splitValues(input); - var inputSpecificFirstCharBlacklist = inputElement.hasAttribute('data-autocomplete-first-character-blacklist') ? inputElement.getAttribute('data-autocomplete-first-character-blacklist') : ''; + var inputSpecificFirstCharDenylist = inputElement.hasAttribute('data-autocomplete-first-character-denylist') ? inputElement.getAttribute('data-autocomplete-first-character-denylist') : ''; if (cardinality > 0 && currentValues.length > cardinality) { return false; } - if (options.firstCharacterBlacklist.indexOf(input[0]) !== -1 || inputSpecificFirstCharBlacklist.indexOf(input[0]) !== -1) { + if (options.firstCharacterDenylist.indexOf(input[0]) !== -1 || inputSpecificFirstCharDenylist.indexOf(input[0]) !== -1) { return false; } @@ -107,7 +108,7 @@ replace: options.replace }); - autocompleteElement.classList.add('awesomplete-input'); + autocompleteElement.classList.add('ui-autocomplete-input'); autocompleteElement.setAttribute('role', 'textbox'); @@ -131,7 +132,7 @@ if (autocomplete.cache[inputId].hasOwnProperty(term)) { awesomplete.list = autocomplete.cache[inputId][term]; awesomplete.evaluate(); - readResults(autocomplete.cache[inputId][term].length); + readResults(awesomplete.ul.children.length); } else { var apiUrl = input.getAttribute('data-autocomplete-path'); var xhr = new XMLHttpRequest(); @@ -170,7 +171,7 @@ replace: replaceInputValue, sort: false, minChars: 1, - firstCharacterBlacklist: ',', + firstCharacterDenylist: ',', autoFirst: false, maxItems: 10 } diff --git a/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php b/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php index b9e1a389d8..bede3bcbb5 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php @@ -69,7 +69,7 @@ public function testEntityReferenceAutocompleteWidget() { $page = $this->getSession()->getPage(); $assert_session = $this->assertSession(); - $autocomplete_field = $assert_session->waitForElement('css', '[name="' . $field_name . '[0][target_id]"].awesomplete-input'); + $autocomplete_field = $assert_session->waitForElement('css', '[name="' . $field_name . '[0][target_id]"].ui-autocomplete-input'); $autocomplete_field->setValue('Test'); $this->getSession()->getDriver()->keyDown($autocomplete_field->getXpath(), ' '); $assert_session->waitOnAutocomplete(); @@ -93,7 +93,7 @@ public function testEntityReferenceAutocompleteWidget() { $this->drupalGet('node/add/page'); $page = $this->getSession()->getPage(); - $autocomplete_field = $assert_session->waitForElement('css', '[name="' . $field_name . '[0][target_id]"].awesomplete-input'); + $autocomplete_field = $assert_session->waitForElement('css', '[name="' . $field_name . '[0][target_id]"].ui-autocomplete-input'); $autocomplete_field->setValue('Test'); $this->getSession()->getDriver()->keyDown($autocomplete_field->getXpath(), ' '); $assert_session->waitOnAutocomplete();