diff --git a/core/modules/media_library/src/Form/AddFormBase.php b/core/modules/media_library/src/Form/AddFormBase.php index c4f4452828..b872493a50 100644 --- a/core/modules/media_library/src/Form/AddFormBase.php +++ b/core/modules/media_library/src/Form/AddFormBase.php @@ -405,8 +405,8 @@ public function removeButtonSubmit(array $form, FormStateInterface $form_state) // Update the list of added media items in the form state. unset($added_media[$delta]); - // Re-key the media items before setting them in the form state. - $form_state->set('media', array_values($added_media))->setRebuild(); + // Update the media items in the form state. + $form_state->set('media', $added_media)->setRebuild(); // Show a message to the user to confirm the media is removed. $this->messenger()->addStatus($this->t('The media item %label has been removed.', ['%label' => $removed_media->label()])); @@ -449,20 +449,24 @@ public function updateFormCallback(array &$form, FormStateInterface $form_state) $response->addCommand(new InvokeCommand('#media-library-add-form-wrapper :tabbable', 'focus')); } // When there are still more items, update the form and shift the focus to - // the next media item. This is technically the item with the same delta - // as the one that has been removed. If the last list item is removed, - // shift focus to the previous item. + // the next media item. If the last list item is removed, shift focus to + // the previous item. else { $response->addCommand(new ReplaceCommand("#$wrapper_id", $form)); - // We need to add 1 to the delta to shift focus to the next item, - // because the 'nth-child' selector starts counting with 1 and the delta - // starts with 0. - $delta = array_slice($triggering_element['#array_parents'], -2, 1)[0]; - if (isset($added_media[$delta])) { - $delta++; + // Try to find the sequence number of the next media item for use in the + // nth-child selector by checking if the delta is bigger than the + // removed delta. If there is no item with a bigger delta, we + // automatically use the sequence number of the previous item. + $removed_delta = array_slice($triggering_element['#array_parents'], -2, 1)[0]; + $nth_child = 0; + foreach ($added_media as $delta => $media) { + $nth_child++; + if ($delta > $removed_delta) { + break; + } } - $response->addCommand(new InvokeCommand(".media-library-add-form__media:nth-child($delta)", 'focus')); + $response->addCommand(new InvokeCommand(".media-library-add-form__media:nth-child($nth_child)", 'focus')); } } // Update the form and shift focus to the added media items. diff --git a/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php b/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php index 7fbc75b2ce..312dbb9330 100644 --- a/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php +++ b/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php @@ -597,6 +597,7 @@ public function testWidgetAnonymous() { public function testWidgetUpload() { $assert_session = $this->assertSession(); $page = $this->getSession()->getPage(); + $driver = $this->getSession()->getDriver(); foreach ($this->getTestFiles('image') as $image) { $extension = pathinfo($image->filename, PATHINFO_EXTENSION); @@ -735,11 +736,6 @@ public function testWidgetUpload() { // Select a media item. $page->find('css', '.media-library-view .js-click-to-select-checkbox input')->click(); $assert_session->pageTextContains('1 item selected'); - - // Multiple uploads should be allowed. - // @todo Add test when https://github.com/minkphp/Mink/issues/358 is closed - $this->assertTrue($assert_session->fieldExists('Add files')->hasAttribute('multiple')); - $page->attachFileToField('Add files', $this->container->get('file_system')->realpath($png_image->uri)); $assert_session->assertWaitOnAjaxRequest(); $page->fillField('Name', 'Unlimited Cardinality Image'); @@ -848,6 +844,59 @@ public function testWidgetUpload() { $this->assertJsCondition('jQuery("#media-library-add-form-wrapper :tabbable").is(":focus")'); $assert_session->elementNotExists('css', '.media-library-add-form__fields'); $assert_session->elementExists('css', '.media-library-menu'); + $page->find('css', '.ui-dialog-titlebar-close')->click(); + + // Assert uploading multiple files. + $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click(); + $assert_session->assertWaitOnAjaxRequest(); + $assert_session->pageTextContains('Add or select media'); + $page->clickLink('Type Three'); + $assert_session->assertWaitOnAjaxRequest(); + $this->assertTrue($assert_session->fieldExists('Add files')->hasAttribute('multiple')); + // Create a list of new files to upload. + $filenames = []; + $remote_paths = []; + foreach(range(1, 3) as $i) { + $path = $file_system->copy($png_image->uri); + $filenames[] = $file_system->basename($path); + $remote_paths[] = $driver->uploadFileAndGetRemoteFilePath($file_system->realpath($path)); + } + $page->findField('Add files')->setValue(implode("\n", $remote_paths)); + $assert_session->assertWaitOnAjaxRequest(); + // Assert the media item fields are shown and the vertical tabs are no + // longer shown. + $assert_session->elementExists('css', '.media-library-add-form__fields'); + $assert_session->elementNotExists('css', '.media-library-menu'); + // Assert all files have been added. + $assert_session->fieldValueEquals('media[0][fields][name][0][value]', $filenames[0]); + $assert_session->fieldValueEquals('media[1][fields][name][0][value]', $filenames[1]); + $assert_session->fieldValueEquals('media[2][fields][name][0][value]', $filenames[2]); + // Set alt texts. + $page->fillField('media[0][fields][field_media_test_image][0][alt]', $filenames[0]); + $page->fillField('media[1][fields][field_media_test_image][0][alt]', $filenames[1]); + $page->fillField('media[2][fields][field_media_test_image][0][alt]', $filenames[2]); + // Remove the second file and assert the focus is shifted to the container + // of the next media item and field values are still correct. + $page->pressButton('media-1-remove-button'); + $this->assertJsCondition('jQuery(".media-library-add-form__media:nth-child(2)").is(":focus")'); + $assert_session->pageTextContains('The media item ' . $filenames[1] . ' has been removed.'); + $assert_session->fieldValueEquals('media[0][fields][name][0][value]', $filenames[0]); + $assert_session->fieldValueEquals('media[0][fields][field_media_test_image][0][alt]', $filenames[0]); + $assert_session->fieldNotExists('media[1][fields][name][0][value]'); + $assert_session->fieldNotExists('media[1][fields][field_media_test_image][0][alt]'); + $assert_session->fieldValueEquals('media[2][fields][name][0][value]', $filenames[2]); + $assert_session->fieldValueEquals('media[2][fields][field_media_test_image][0][alt]', $filenames[2]); + // Remove the last file and assert the focus is shifted to the container + // of the first media item and field values are still correct. + $page->pressButton('media-2-remove-button'); + $this->assertJsCondition('jQuery(".media-library-add-form__media:nth-child(1)").is(":focus")'); + $assert_session->pageTextContains('The media item ' . $filenames[2] . ' has been removed.'); + $assert_session->fieldValueEquals('media[0][fields][name][0][value]', $filenames[0]); + $assert_session->fieldValueEquals('media[0][fields][field_media_test_image][0][alt]', $filenames[0]); + $assert_session->fieldNotExists('media[1][fields][name][0][value]'); + $assert_session->fieldNotExists('media[1][fields][field_media_test_image][0][alt]'); + $assert_session->fieldNotExists('media[2][fields][name][0][value]'); + $assert_session->fieldNotExists('media[2][fields][field_media_test_image][0][alt]'); } /**