From 110890965648c68e42d90d62159ceb28221934b1 Mon Sep 17 00:00:00 2001
From: Lee Rowlands <lee.rowlands@previousnext.com.au>
Date: Fri, 11 Oct 2019 10:54:43 +1000
Subject: [PATCH] =?UTF-8?q?Issue=20#2863188=20by=20acbramley,=20Erik=20Fr?=
 =?UTF-8?q?=C3=A8rejean,=20Maouna,=20andypost,=20init90,=20larowlan,=20hch?=
 =?UTF-8?q?onov,=20sathish.redcrackle,=20vasi1186,=20chr.fritsch,=20tstoec?=
 =?UTF-8?q?kler,=20Krzysztof=20Doma=C5=84ski,=20phjou,=20jibran,=20alexpot?=
 =?UTF-8?q?t,=20catch,=20xjm:=20Hardcoded=20result=20size=20limit=20in=20t?=
 =?UTF-8?q?he=20entity=20reference=20autocomplete=20widget?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 core/config/schema/core.entity.schema.yml     |  6 ++
 .../Core/Entity/EntityAutocompleteMatcher.php |  3 +-
 .../EntityReferenceAutocompleteWidget.php     | 15 ++++-
 ....entity_form_display.node.book.default.yml |  1 +
 ...entity_form_display.node.forum.default.yml |  1 +
 .../src/Functional/EntityFormDisplayTest.php  |  1 +
 ...y_form_display.media.type_five.default.yml |  1 +
 ...y_form_display.media.type_four.default.yml |  1 +
 ...ty_form_display.media.type_one.default.yml |  1 +
 ..._form_display.media.type_three.default.yml |  1 +
 ...ty_form_display.media.type_two.default.yml |  1 +
 ...y_form_display.node.basic_page.default.yml |  1 +
 ...play.node.options_install_test.default.yml |  1 +
 core/modules/system/system.module             | 31 +++++++++
 core/modules/system/system.post_update.php    | 27 ++++++++
 ...AutocompleteWidgetMatchLimitUpdateTest.php | 44 +++++++++++++
 ...ntity_form_display.media.audio.default.yml |  1 +
 ...ty_form_display.media.document.default.yml |  1 +
 ...ntity_form_display.media.image.default.yml |  1 +
 ...orm_display.media.remote_video.default.yml |  1 +
 ...ntity_form_display.media.video.default.yml |  1 +
 ...tity_form_display.node.article.default.yml |  2 +
 ....entity_form_display.node.page.default.yml |  1 +
 ...ntity_form_display.node.recipe.default.yml |  3 +
 ...tity_form_display.node.article.default.yml |  2 +
 ....entity_form_display.node.page.default.yml |  1 +
 ...ntity_form_display.media.audio.default.yml |  1 +
 ...ty_form_display.media.document.default.yml |  1 +
 ...ntity_form_display.media.image.default.yml |  1 +
 ...orm_display.media.remote_video.default.yml |  1 +
 ...ntity_form_display.media.video.default.yml |  1 +
 .../EntityReferenceAutocompleteWidgetTest.php | 66 +++++++++++++++++--
 .../EntityFormDisplayResourceTestBase.php     |  1 +
 33 files changed, 213 insertions(+), 9 deletions(-)
 create mode 100644 core/modules/system/tests/src/Functional/Update/EntityReferenceAutocompleteWidgetMatchLimitUpdateTest.php

diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml
index 81c03dbca074..8850d40ef7be 100644
--- a/core/config/schema/core.entity.schema.yml
+++ b/core/config/schema/core.entity.schema.yml
@@ -234,6 +234,9 @@ field.widget.settings.entity_reference_autocomplete_tags:
     match_operator:
       type: string
       label: 'Autocomplete matching'
+    match_limit:
+      type: integer
+      label: 'Maximum number of autocomplete suggestions.'
     size:
       type: integer
       label: 'Size of textfield'
@@ -248,6 +251,9 @@ field.widget.settings.entity_reference_autocomplete:
     match_operator:
       type: string
       label: 'Autocomplete matching'
+    match_limit:
+      type: integer
+      label: 'Maximum number of autocomplete suggestions.'
     size:
       type: integer
       label: 'Size of textfield'
diff --git a/core/lib/Drupal/Core/Entity/EntityAutocompleteMatcher.php b/core/lib/Drupal/Core/Entity/EntityAutocompleteMatcher.php
index 2cede4dffaa5..93a8539ced9b 100644
--- a/core/lib/Drupal/Core/Entity/EntityAutocompleteMatcher.php
+++ b/core/lib/Drupal/Core/Entity/EntityAutocompleteMatcher.php
@@ -61,7 +61,8 @@ public function getMatches($target_type, $selection_handler, $selection_settings
     if (isset($string)) {
       // Get an array of matching entities.
       $match_operator = !empty($selection_settings['match_operator']) ? $selection_settings['match_operator'] : 'CONTAINS';
-      $entity_labels = $handler->getReferenceableEntities($string, $match_operator, 10);
+      $match_limit = isset($selection_settings['match_limit']) ? (int) $selection_settings['match_limit'] : 10;
+      $entity_labels = $handler->getReferenceableEntities($string, $match_operator, $match_limit);
 
       // Loop through the entities and convert them into autocomplete output.
       foreach ($entity_labels as $values) {
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php
index cea4ecb7e97d..af3c80a9b061 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php
@@ -28,6 +28,7 @@ class EntityReferenceAutocompleteWidget extends WidgetBase {
   public static function defaultSettings() {
     return [
       'match_operator' => 'CONTAINS',
+      'match_limit' => 10,
       'size' => 60,
       'placeholder' => '',
     ] + parent::defaultSettings();
@@ -44,6 +45,13 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
       '#options' => $this->getMatchOperatorOptions(),
       '#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of entities.'),
     ];
+    $element['match_limit'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Number of results'),
+      '#default_value' => $this->getSetting('match_limit'),
+      '#min' => 0,
+      '#description' => $this->t('The number of suggestions that will be listed. Use <em>0</em> to remove the limit.'),
+    ];
     $element['size'] = [
       '#type' => 'number',
       '#title' => t('Size of textfield'),
@@ -68,6 +76,8 @@ public function settingsSummary() {
 
     $operators = $this->getMatchOperatorOptions();
     $summary[] = t('Autocomplete matching: @match_operator', ['@match_operator' => $operators[$this->getSetting('match_operator')]]);
+    $size = $this->getSetting('match_limit') ?: $this->t('unlimited');
+    $summary[] = $this->t('Autocomplete suggestion list size: @size', ['@size' => $size]);
     $summary[] = t('Textfield size: @size', ['@size' => $this->getSetting('size')]);
     $placeholder = $this->getSetting('placeholder');
     if (!empty($placeholder)) {
@@ -88,7 +98,10 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     $referenced_entities = $items->referencedEntities();
 
     // Append the match operation to the selection settings.
-    $selection_settings = $this->getFieldSetting('handler_settings') + ['match_operator' => $this->getSetting('match_operator')];
+    $selection_settings = $this->getFieldSetting('handler_settings') + [
+      'match_operator' => $this->getSetting('match_operator'),
+      'match_limit' => $this->getSetting('match_limit'),
+    ];
 
     $element += [
       '#type' => 'entity_autocomplete',
diff --git a/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml b/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml
index b65b723be856..4b7f304c27c2 100644
--- a/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml
+++ b/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml
@@ -62,6 +62,7 @@ content:
     region: content
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     third_party_settings: {  }
diff --git a/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml b/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
index 3cc25603ee20..2f87d23d5955 100644
--- a/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
+++ b/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
@@ -77,6 +77,7 @@ content:
     region: content
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     third_party_settings: {  }
diff --git a/core/modules/jsonapi/tests/src/Functional/EntityFormDisplayTest.php b/core/modules/jsonapi/tests/src/Functional/EntityFormDisplayTest.php
index b28efdb8fb06..73190d265555 100644
--- a/core/modules/jsonapi/tests/src/Functional/EntityFormDisplayTest.php
+++ b/core/modules/jsonapi/tests/src/Functional/EntityFormDisplayTest.php
@@ -139,6 +139,7 @@ protected function getExpectedDocument() {
               'weight' => 5,
               'settings' => [
                 'match_operator' => 'CONTAINS',
+                'match_limit' => 10,
                 'size' => 60,
                 'placeholder' => '',
               ],
diff --git a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_five.default.yml b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_five.default.yml
index 8deaa648b7e4..98206155d25b 100644
--- a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_five.default.yml
+++ b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_five.default.yml
@@ -51,6 +51,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_four.default.yml b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_four.default.yml
index 40d4d1bd31c0..5303563d91d6 100644
--- a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_four.default.yml
+++ b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_four.default.yml
@@ -62,6 +62,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_one.default.yml b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_one.default.yml
index 212daf818796..2e07c3d2194f 100644
--- a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_one.default.yml
+++ b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_one.default.yml
@@ -36,6 +36,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_three.default.yml b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_three.default.yml
index ea7248e2aa3e..c70d348c779a 100644
--- a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_three.default.yml
+++ b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_three.default.yml
@@ -53,6 +53,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_two.default.yml b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_two.default.yml
index fabd13b0297b..acc954e827eb 100644
--- a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_two.default.yml
+++ b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.media.type_two.default.yml
@@ -36,6 +36,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.node.basic_page.default.yml b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.node.basic_page.default.yml
index 6df6518481a3..0fd908e713ee 100644
--- a/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.node.basic_page.default.yml
+++ b/core/modules/media_library/tests/modules/media_library_test/config/install/core.entity_form_display.node.basic_page.default.yml
@@ -95,6 +95,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml b/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml
index 1b703217676d..aecc9590fd01 100644
--- a/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml
+++ b/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml
@@ -25,6 +25,7 @@ content:
     region: content
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     third_party_settings: {  }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index dc1509ab9110..16337f54409f 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -15,6 +15,8 @@
 use Drupal\Core\Database\Query\AlterableInterface;
 use Drupal\Core\Extension\Dependency;
 use Drupal\Core\Extension\Extension;
+use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
+use Drupal\Core\Field\Plugin\Field\FieldWidget\EntityReferenceAutocompleteWidget;
 use Drupal\Core\File\Exception\FileException;
 use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Form\FormStateInterface;
@@ -1466,3 +1468,32 @@ function system_modules_uninstalled($modules) {
     }
   }
 }
+
+/**
+ * Implements hook_ENTITY_TYPE_presave() for entity_form_display entities.
+ *
+ * Provides a BC layer for modules providing old configurations.
+ *
+ * @todo Remove this hook in Drupal 9.0.x https://www.drupal.org/project/drupal/issues/3086388
+ */
+function system_entity_form_display_presave(EntityFormDisplayInterface $display) {
+  /** @var \Drupal\Core\Field\WidgetPluginManager $field_widget_manager */
+  $field_widget_manager = \Drupal::service('plugin.manager.field.widget');
+
+  foreach ($display->getComponents() as $field_name => $component) {
+    if (empty($component['type'])) {
+      continue;
+    }
+
+    $plugin_definition = $field_widget_manager->getDefinition($component['type'], FALSE);
+    if (!is_a($plugin_definition['class'], EntityReferenceAutocompleteWidget::class, TRUE)) {
+      continue;
+    }
+
+    if (!isset($component['settings']['match_limit'])) {
+      @trigger_error(sprintf('Any entity_reference_autocomplete component of an entity_form_display must have a match_limit setting. The %s field on the %s form display is missing it. This BC layer will be removed before 9.0.0. See https://www.drupal.org/node/2863188', $field_name, $display->id()), E_USER_DEPRECATED);
+      $component['settings']['match_limit'] = 10;
+      $display->setComponent($field_name, $component);
+    }
+  }
+}
diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php
index 5f6c9f766348..114d28912022 100644
--- a/core/modules/system/system.post_update.php
+++ b/core/modules/system/system.post_update.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
+use Drupal\Core\Field\Plugin\Field\FieldWidget\EntityReferenceAutocompleteWidget;
 
 /**
  * Re-save all configuration entities to recalculate dependencies.
@@ -213,3 +214,29 @@ function system_post_update_clear_menu_cache() {
 function system_post_update_layout_plugin_schema_change() {
   // Empty post-update hook.
 }
+
+/**
+ * Populate the new 'match_limit' setting for the ER autocomplete widget.
+ */
+function system_post_update_entity_reference_autocomplete_match_limit(&$sandbox = NULL) {
+  $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class);
+  /** @var \Drupal\Core\Field\WidgetPluginManager $field_widget_manager */
+  $field_widget_manager = \Drupal::service('plugin.manager.field.widget');
+
+  $callback = function (EntityDisplayInterface $display) use ($field_widget_manager) {
+    foreach ($display->getComponents() as $field_name => $component) {
+      if (empty($component['type'])) {
+        continue;
+      }
+
+      $plugin_definition = $field_widget_manager->getDefinition($component['type'], FALSE);
+      if (is_a($plugin_definition['class'], EntityReferenceAutocompleteWidget::class, TRUE)) {
+        return TRUE;
+      }
+    }
+
+    return FALSE;
+  };
+
+  $config_entity_updater->update($sandbox, 'entity_form_display', $callback);
+}
diff --git a/core/modules/system/tests/src/Functional/Update/EntityReferenceAutocompleteWidgetMatchLimitUpdateTest.php b/core/modules/system/tests/src/Functional/Update/EntityReferenceAutocompleteWidgetMatchLimitUpdateTest.php
new file mode 100644
index 000000000000..fa196a88a40e
--- /dev/null
+++ b/core/modules/system/tests/src/Functional/Update/EntityReferenceAutocompleteWidgetMatchLimitUpdateTest.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Drupal\Tests\system\Functional\Update;
+
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
+
+/**
+ * Tests that the match_limit setting is added to entity_reference_autocomplete.
+ *
+ * @see system_post_update_entity_reference_autocomplete_match_limit()
+ *
+ * @group legacy
+ */
+class EntityReferenceAutocompleteWidgetMatchLimitUpdateTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
+    ];
+  }
+
+  /**
+   * Tests that the match_limit setting is added to the config.
+   *
+   * @expectedDeprecation Any entity_reference_autocomplete component of an entity_form_display must have a match_limit setting. The field_tags field on the node.article.default form display is missing it. This BC layer will be removed before 9.0.0. See https://www.drupal.org/node/2863188
+   * @expectedDeprecation Any entity_reference_autocomplete component of an entity_form_display must have a match_limit setting. The uid field on the node.article.default form display is missing it. This BC layer will be removed before 9.0.0. See https://www.drupal.org/node/2863188
+   */
+  public function testViewsPostUpdateEntityLinkUrl() {
+    $display = EntityFormDisplay::load('node.article.default');
+    $this->assertArrayNotHasKey('match_limit', $display->getComponent('field_tags')['settings']);
+    $this->assertArrayNotHasKey('match_limit', $display->getComponent('uid')['settings']);
+
+    $this->runUpdates();
+
+    $display = EntityFormDisplay::load('node.article.default');
+    $this->assertEquals(10, $display->getComponent('field_tags')['settings']['match_limit']);
+    $this->assertEquals(10, $display->getComponent('uid')['settings']['match_limit']);
+  }
+
+}
diff --git a/core/profiles/demo_umami/config/install/core.entity_form_display.media.audio.default.yml b/core/profiles/demo_umami/config/install/core.entity_form_display.media.audio.default.yml
index a359bdf5a352..ac659d316055 100644
--- a/core/profiles/demo_umami/config/install/core.entity_form_display.media.audio.default.yml
+++ b/core/profiles/demo_umami/config/install/core.entity_form_display.media.audio.default.yml
@@ -50,6 +50,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/profiles/demo_umami/config/install/core.entity_form_display.media.document.default.yml b/core/profiles/demo_umami/config/install/core.entity_form_display.media.document.default.yml
index 489716bb1c89..971b5c28ebdc 100644
--- a/core/profiles/demo_umami/config/install/core.entity_form_display.media.document.default.yml
+++ b/core/profiles/demo_umami/config/install/core.entity_form_display.media.document.default.yml
@@ -50,6 +50,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/profiles/demo_umami/config/install/core.entity_form_display.media.image.default.yml b/core/profiles/demo_umami/config/install/core.entity_form_display.media.image.default.yml
index 237009bd4482..3e83e1c38735 100644
--- a/core/profiles/demo_umami/config/install/core.entity_form_display.media.image.default.yml
+++ b/core/profiles/demo_umami/config/install/core.entity_form_display.media.image.default.yml
@@ -52,6 +52,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/profiles/demo_umami/config/install/core.entity_form_display.media.remote_video.default.yml b/core/profiles/demo_umami/config/install/core.entity_form_display.media.remote_video.default.yml
index baed30de3761..9ff0e4538269 100644
--- a/core/profiles/demo_umami/config/install/core.entity_form_display.media.remote_video.default.yml
+++ b/core/profiles/demo_umami/config/install/core.entity_form_display.media.remote_video.default.yml
@@ -51,6 +51,7 @@ content:
     weight: 4
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/profiles/demo_umami/config/install/core.entity_form_display.media.video.default.yml b/core/profiles/demo_umami/config/install/core.entity_form_display.media.video.default.yml
index 90fb03f73ba2..b9340255334a 100644
--- a/core/profiles/demo_umami/config/install/core.entity_form_display.media.video.default.yml
+++ b/core/profiles/demo_umami/config/install/core.entity_form_display.media.video.default.yml
@@ -50,6 +50,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/profiles/demo_umami/config/install/core.entity_form_display.node.article.default.yml b/core/profiles/demo_umami/config/install/core.entity_form_display.node.article.default.yml
index 4e3d69e156ef..b3b36b6accc1 100644
--- a/core/profiles/demo_umami/config/install/core.entity_form_display.node.article.default.yml
+++ b/core/profiles/demo_umami/config/install/core.entity_form_display.node.article.default.yml
@@ -48,6 +48,7 @@ content:
     region: content
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     third_party_settings: {  }
@@ -110,6 +111,7 @@ content:
     region: content
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     third_party_settings: {  }
diff --git a/core/profiles/demo_umami/config/install/core.entity_form_display.node.page.default.yml b/core/profiles/demo_umami/config/install/core.entity_form_display.node.page.default.yml
index 2bd498a57783..97fb4e243bb3 100644
--- a/core/profiles/demo_umami/config/install/core.entity_form_display.node.page.default.yml
+++ b/core/profiles/demo_umami/config/install/core.entity_form_display.node.page.default.yml
@@ -89,6 +89,7 @@ content:
     region: content
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     third_party_settings: {  }
diff --git a/core/profiles/demo_umami/config/install/core.entity_form_display.node.recipe.default.yml b/core/profiles/demo_umami/config/install/core.entity_form_display.node.recipe.default.yml
index 3a62a517edaf..44b7859c0cac 100644
--- a/core/profiles/demo_umami/config/install/core.entity_form_display.node.recipe.default.yml
+++ b/core/profiles/demo_umami/config/install/core.entity_form_display.node.recipe.default.yml
@@ -79,6 +79,7 @@ content:
     weight: 6
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     third_party_settings: {  }
@@ -104,6 +105,7 @@ content:
     weight: 7
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     third_party_settings: {  }
@@ -167,6 +169,7 @@ content:
     weight: 12
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
index 43c904fd2ace..1f7102dd49ed 100644
--- a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
+++ b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
@@ -54,6 +54,7 @@ content:
     region: content
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     third_party_settings: {  }
@@ -98,6 +99,7 @@ content:
     region: content
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     third_party_settings: {  }
diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
index c4c7ef57537c..342988cbe27e 100644
--- a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
+++ b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
@@ -69,6 +69,7 @@ content:
     region: content
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     third_party_settings: {  }
diff --git a/core/profiles/standard/config/optional/core.entity_form_display.media.audio.default.yml b/core/profiles/standard/config/optional/core.entity_form_display.media.audio.default.yml
index a30d8d24e8ec..f016c1ee47b5 100644
--- a/core/profiles/standard/config/optional/core.entity_form_display.media.audio.default.yml
+++ b/core/profiles/standard/config/optional/core.entity_form_display.media.audio.default.yml
@@ -43,6 +43,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/profiles/standard/config/optional/core.entity_form_display.media.document.default.yml b/core/profiles/standard/config/optional/core.entity_form_display.media.document.default.yml
index 1e58abd1ae84..82cedc37e0cf 100644
--- a/core/profiles/standard/config/optional/core.entity_form_display.media.document.default.yml
+++ b/core/profiles/standard/config/optional/core.entity_form_display.media.document.default.yml
@@ -36,6 +36,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/profiles/standard/config/optional/core.entity_form_display.media.image.default.yml b/core/profiles/standard/config/optional/core.entity_form_display.media.image.default.yml
index 9184298ce04d..1203f9415998 100644
--- a/core/profiles/standard/config/optional/core.entity_form_display.media.image.default.yml
+++ b/core/profiles/standard/config/optional/core.entity_form_display.media.image.default.yml
@@ -38,6 +38,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/profiles/standard/config/optional/core.entity_form_display.media.remote_video.default.yml b/core/profiles/standard/config/optional/core.entity_form_display.media.remote_video.default.yml
index 4752e75274ac..3fe271b4f73a 100644
--- a/core/profiles/standard/config/optional/core.entity_form_display.media.remote_video.default.yml
+++ b/core/profiles/standard/config/optional/core.entity_form_display.media.remote_video.default.yml
@@ -44,6 +44,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/profiles/standard/config/optional/core.entity_form_display.media.video.default.yml b/core/profiles/standard/config/optional/core.entity_form_display.media.video.default.yml
index a58d130bfb4a..f1001d6c7b7b 100644
--- a/core/profiles/standard/config/optional/core.entity_form_display.media.video.default.yml
+++ b/core/profiles/standard/config/optional/core.entity_form_display.media.video.default.yml
@@ -43,6 +43,7 @@ content:
     weight: 5
     settings:
       match_operator: CONTAINS
+      match_limit: 10
       size: 60
       placeholder: ''
     region: content
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php b/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php
index e1f580fce781..fe4c9cf6c643 100644
--- a/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php
+++ b/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php
@@ -21,7 +21,7 @@ class EntityReferenceAutocompleteWidgetTest extends WebDriverTestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['node'];
+  public static $modules = ['node', 'field_ui'];
 
   /**
    * {@inheritdoc}
@@ -51,7 +51,7 @@ public function testEntityReferenceAutocompleteWidget() {
     // Create an entity reference field and use the default 'CONTAINS' match
     // operator.
     $field_name = 'field_test';
-    $this->createEntityReferenceField('node', 'page', $field_name, $field_name, 'node', 'default', ['target_bundles' => ['page']]);
+    $this->createEntityReferenceField('node', 'page', $field_name, $field_name, 'node', 'default', ['target_bundles' => ['page'], 'sort' => ['field' => 'title', 'direction' => 'DESC']]);
     $form_display = $display_repository->getFormDisplay('node', 'page');
     $form_display->setComponent($field_name, [
       'type' => 'entity_reference_autocomplete',
@@ -92,18 +92,70 @@ public function testEntityReferenceAutocompleteWidget() {
       ->save();
 
     $this->drupalGet('node/add/page');
-    $page = $this->getSession()->getPage();
 
-    $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();
+    $this->doAutocomplete($field_name);
 
     $results = $page->findAll('css', '.ui-autocomplete li');
 
     $this->assertCount(1, $results);
     $assert_session->pageTextContains('Test page');
     $assert_session->pageTextNotContains('Page test');
+
+    // Change the size of the result set.
+    $display_repository->getFormDisplay('node', 'page')
+      ->setComponent($field_name, [
+        'type' => 'entity_reference_autocomplete',
+        'settings' => [
+          'match_limit' => 1,
+        ],
+      ])
+      ->save();
+
+    $this->drupalGet('node/add/page');
+
+    $this->doAutocomplete($field_name);
+    $results = $page->findAll('css', '.ui-autocomplete li');
+
+    $this->assertCount(1, $results);
+    $assert_session->pageTextContains('Test page');
+    $assert_session->pageTextNotContains('Page test');
+
+    // Change the size of the result set via the UI.
+    $this->drupalLogin($this->createUser([
+        'access content',
+        'administer content types',
+        'administer node fields',
+        'administer node form display',
+        'create page content',
+      ]
+    ));
+    $this->drupalGet('/admin/structure/types/manage/page/form-display');
+    $assert_session->pageTextContains('Autocomplete suggestion list size: 1');
+    // Click on the widget settings button to open the widget settings form.
+    $this->drupalPostForm(NULL, [], $field_name . "_settings_edit");
+    $this->assertSession()->waitForElement('css', sprintf('[name="fields[%s][settings_edit_form][settings][match_limit]"]', $field_name));
+    $page->fillField('Number of results', 2);
+    $page->pressButton('Save');
+    $assert_session->pageTextContains('Your settings have been saved.');
+    $assert_session->pageTextContains('Autocomplete suggestion list size: 2');
+
+    $this->drupalGet('node/add/page');
+
+    $this->doAutocomplete($field_name);
+    $this->assertCount(2, $page->findAll('css', '.ui-autocomplete li'));
+  }
+
+  /**
+   * Executes an autocomplete on a given field and waits for it to finish.
+   *
+   * @param string $field_name
+   *   The field name.
+   */
+  protected function doAutocomplete($field_name) {
+    $autocomplete_field = $this->getSession()->getPage()->findField($field_name . '[0][target_id]');
+    $autocomplete_field->setValue('Test');
+    $this->getSession()->getDriver()->keyDown($autocomplete_field->getXpath(), ' ');
+    $this->assertSession()->waitOnAutocomplete();
   }
 
 }
diff --git a/core/tests/Drupal/FunctionalTests/Rest/EntityFormDisplayResourceTestBase.php b/core/tests/Drupal/FunctionalTests/Rest/EntityFormDisplayResourceTestBase.php
index a44534a31f0c..78df2a752025 100644
--- a/core/tests/Drupal/FunctionalTests/Rest/EntityFormDisplayResourceTestBase.php
+++ b/core/tests/Drupal/FunctionalTests/Rest/EntityFormDisplayResourceTestBase.php
@@ -109,6 +109,7 @@ protected function getExpectedNormalizedEntity() {
           'weight' => 5,
           'settings' => [
             'match_operator' => 'CONTAINS',
+            'match_limit' => 10,
             'size' => 60,
             'placeholder' => '',
           ],
-- 
GitLab