diff --git a/core/modules/media_library/js/media_library.ui.es6.js b/core/modules/media_library/js/media_library.ui.es6.js index dff15e6a7b..0d0c5b539b 100644 --- a/core/modules/media_library/js/media_library.ui.es6.js +++ b/core/modules/media_library/js/media_library.ui.es6.js @@ -8,51 +8,16 @@ Drupal.MediaLibrary = { /** * When a user interacts with the media library we want the selection to - * persist as long as the media library modal is opened. We temporarily + * persist as long as the media library modal is open. We temporarily * store the selected items while the user filters the media library view or * navigates to different tabs. */ currentSelection: [], - }; - - /** - * Add a message to the media library. - * - * @param {string} message - * The message to add. - * @param {string} messageId - * The message ID. - * @param {string} messageType - * The type of message. - */ - function addMediaLibraryMessage(message, messageId, messageType) { - const wrapper = document.querySelector('.js-media-library-messages'); - if (!wrapper) { - return; + getSelectedCount: function () { + return this.currentSelection.length + $('.js-media-library-add-form__media').length } - - const messages = new Drupal.Message(wrapper); - messages.clear(); - messages.add(message, { - type: messageType, - id: messageId, - }); - } - - /** - * Clear messages. - */ - function clearMediaLibraryMessages() { - const wrapper = document.querySelector('.js-media-library-messages'); - - if (!wrapper) { - return; - } - - const messages = new Drupal.Message(wrapper); - messages.clear(); - } + }; /** * Command to update the current media library selection. @@ -434,6 +399,7 @@ currentSelection.length + $('.js-media-library-add-form__media').length; const diff = selectedMediaCount - availableSlots; + const messages = new Drupal.Message('.js-media-library-messages'); if (diff > 0) { const message = Drupal.formatPlural( diff, @@ -441,9 +407,14 @@ 'There are currently @total items selected. The maximum number of remaining items for the field is @max. Please remove @count items from the selection.', { '@total': selectedMediaCount, '@max': availableSlots }, ); - addMediaLibraryMessage(message, 'maxItemsExceeded', 'warning'); + messages.clear(); + messages.add(message, { + type: 'warning', + id: 'maxItemsExceeded', + options: { 'priority': 'assertive' } + }); } else { - clearMediaLibraryMessages(); + messages.clear(); } } diff --git a/core/modules/media_library/js/media_library.ui.js b/core/modules/media_library/js/media_library.ui.js index 265e58e5c1..2b30ab9c29 100644 --- a/core/modules/media_library/js/media_library.ui.js +++ b/core/modules/media_library/js/media_library.ui.js @@ -7,34 +7,12 @@ (function ($, Drupal, window) { Drupal.MediaLibrary = { - currentSelection: [] - }; - - function addMediaLibraryMessage(message, messageId, messageType) { - var wrapper = document.querySelector('.js-media-library-messages'); + currentSelection: [], - if (!wrapper) { - return; + getSelectedCount: function getSelectedCount() { + return this.currentSelection.length; } - - var messages = new Drupal.Message(wrapper); - messages.clear(); - messages.add(message, { - type: messageType, - id: messageId - }); - } - - function clearMediaLibraryMessages() { - var wrapper = document.querySelector('.js-media-library-messages'); - - if (!wrapper) { - return; - } - - var messages = new Drupal.Message(wrapper); - messages.clear(); - } + }; Drupal.AjaxCommands.prototype.updateMediaLibrarySelection = function (ajax, response, status) { Object.values(response.mediaIds).forEach(function (value) { @@ -222,11 +200,17 @@ if (availableSlots > 0) { var selectedMediaCount = currentSelection.length + $('.js-media-library-add-form__media').length; var diff = selectedMediaCount - availableSlots; + var messages = new Drupal.Message('.js-media-library-messages'); if (diff > 0) { var message = Drupal.formatPlural(diff, 'There are currently @total items selected. The maximum number of remaining items for the field is @max. Please remove @count item from the selection.', 'There are currently @total items selected. The maximum number of remaining items for the field is @max. Please remove @count items from the selection.', { '@total': selectedMediaCount, '@max': availableSlots }); - addMediaLibraryMessage(message, 'maxItemsExceeded', 'warning'); + messages.clear(); + messages.add(message, { + type: 'warning', + id: 'maxItemsExceeded', + options: { 'priority': 'assertive' } + }); } else { - clearMediaLibraryMessages(); + messages.clear(); } } diff --git a/core/modules/media_library/src/Form/AddFormBase.php b/core/modules/media_library/src/Form/AddFormBase.php index 2e993e4aba..1ed311f437 100644 --- a/core/modules/media_library/src/Form/AddFormBase.php +++ b/core/modules/media_library/src/Form/AddFormBase.php @@ -461,9 +461,6 @@ protected function buildActions(array $form, FormStateInterface $form_state) { 'callback' => '::updateLibrary', 'wrapper' => 'media-library-add-form-wrapper', ], - '#attributes' => [ - 'class' => ['js-media-library-select-button'], - ], ], ]; if ($this->isAdvancedUi()) { diff --git a/core/modules/media_library/src/MediaLibraryEditorOpener.php b/core/modules/media_library/src/MediaLibraryEditorOpener.php index f7ec74c311..a18b5bd7f0 100644 --- a/core/modules/media_library/src/MediaLibraryEditorOpener.php +++ b/core/modules/media_library/src/MediaLibraryEditorOpener.php @@ -69,11 +69,9 @@ public function getSelectionResponse(MediaLibraryState $state, array $selected_i $response = new AjaxResponse(); try { - $this->validateAvailableSlots($state, $selected_ids); + $this->validateSelection($state, $selected_ids); } catch (\InvalidArgumentException $e) { - // The message ID should be the same as the client side ID. - // @see Drupal.behaviors.MediaLibraryItemSelection $command = new MessageCommand($e->getMessage(), '.js-media-library-messages', ['type' => 'error']); return $response->addCommand($command); } diff --git a/core/modules/media_library/src/MediaLibraryFieldWidgetOpener.php b/core/modules/media_library/src/MediaLibraryFieldWidgetOpener.php index 392fca1a3e..3cf60c14bc 100644 --- a/core/modules/media_library/src/MediaLibraryFieldWidgetOpener.php +++ b/core/modules/media_library/src/MediaLibraryFieldWidgetOpener.php @@ -111,11 +111,9 @@ public function getSelectionResponse(MediaLibraryState $state, array $selected_i $response = new AjaxResponse(); try { - $this->validateAvailableSlots($state, $selected_ids); + $this->validateSelection($state, $selected_ids); } catch (\InvalidArgumentException $e) { - // The message ID should be the same as the client side ID. - // @see Drupal.behaviors.MediaLibraryItemSelection $command = new MessageCommand($e->getMessage(), '.js-media-library-messages', ['type' => 'error']); return $response->addCommand($command); } diff --git a/core/modules/media_library/src/MediaLibraryOpenerBase.php b/core/modules/media_library/src/MediaLibraryOpenerBase.php index 16a75b65a0..81746a60e4 100644 --- a/core/modules/media_library/src/MediaLibraryOpenerBase.php +++ b/core/modules/media_library/src/MediaLibraryOpenerBase.php @@ -8,14 +8,26 @@ use StringTranslationTrait; - protected function validateAvailableSlots(MediaLibraryState $state, array $selected_ids) { - // If the total number of selected items exceeds the number of allowed - // items, throw an exception. If the remaining number of items is negative, - // allow an unlimited number of items. + /** + * Validate the selection. + * + * @param \Drupal\media_library\MediaLibraryState $state + * The state the media library was in at the time of selection. + * @param int[] $selected_ids + * The IDs of the selected media items. + * + * @throws \InvalidArgumentException + * Thrown if the total number of selected items exceeds the number of + * allowed items. + */ + protected function validateSelection(MediaLibraryState $state, array $selected_ids) { + if ($state->hasUnlimitedSlotsAvailable()) { + return; + } $available_slots = $state->getAvailableSlots(); $selected_count = count($selected_ids); - if ($available_slots > 0 && $selected_count > $available_slots) { + if ($selected_count > $available_slots) { $error = $this->formatPlural($selected_count - $available_slots, 'There are currently @total items selected, but the maximum number of remaining items for the field is @max. Please remove @count item from the selection.', 'There are currently @total items selected. The maximum number of remaining items for the field is @max. Please remove @count items from the selection.', [ '@total' => $selected_count, '@max' => $available_slots, diff --git a/core/modules/media_library/src/MediaLibraryState.php b/core/modules/media_library/src/MediaLibraryState.php index 258f19ded1..f63a9fb6ce 100644 --- a/core/modules/media_library/src/MediaLibraryState.php +++ b/core/modules/media_library/src/MediaLibraryState.php @@ -250,6 +250,19 @@ public function hasSlotsAvailable() { return $this->getAvailableSlots() !== 0; } + /** + * Determines if unlimited media items can be selected. + * + * When ::getAvailableSlots() returns a negative integer, an unlimited amount + * of media items can be selected. + * + * @return bool + * TRUE if an unlimited number of items can be selected, otherwise FALSE. + */ + public function hasUnlimitedSlotsAvailable() { + return $this->getAvailableSlots() < 0; + } + /** * Returns the number of additional media items that can be selected. * diff --git a/core/modules/media_library/src/Plugin/views/field/MediaLibrarySelectForm.php b/core/modules/media_library/src/Plugin/views/field/MediaLibrarySelectForm.php index ecba3bb9ff..3003242dca 100644 --- a/core/modules/media_library/src/Plugin/views/field/MediaLibrarySelectForm.php +++ b/core/modules/media_library/src/Plugin/views/field/MediaLibrarySelectForm.php @@ -142,8 +142,6 @@ public static function updateWidget(array &$form, FormStateInterface $form_state // Show an error message when the user did not select any items. if (!$selected_media_count) { $response = new AjaxResponse(); - // The message ID should be the same as the client side ID. - // @see Drupal.behaviors.MediaLibraryItemSelection $response->addCommand(new MessageCommand(t('No media items selected.'), '.js-media-library-messages', ['type' => 'error'])); return $response; }