Unverified Commit 58d6b442 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3035316 by seanB, andrewmacpherson, oknate, phenaproxima, rainbreaw:...

Issue #3035316 by seanB, andrewmacpherson, oknate, phenaproxima, rainbreaw: ‘Add media’ in MediaLibraryWidget should be a button, not a link
parent 2b5a0b53
Loading
Loading
Loading
Loading
+1 −0
Changes for core/modules/media_library/media_library.libraries.yml: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ widget:
  js:
    js/media_library.widget.js: {}
  dependencies:
    - core/drupal.dialog.ajax
    - core/jquery.ui.sortable
    - core/jquery.once
    - media_library/style
+1 −2
Changes for core/modules/media_library/src/Form/AddFormBase.php: 1 added line, 2 removed lines.
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@
use Drupal\media\MediaInterface;
use Drupal\media\MediaTypeInterface;
use Drupal\media_library\Ajax\UpdateSelectionCommand;
use Drupal\media_library\MediaLibraryState;
use Drupal\media_library\MediaLibraryUiBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;

@@ -420,7 +419,7 @@ public function updateWidget(array &$form, FormStateInterface $form_state) {
    // contains the vertical tabs. Besides that, we also need to force the media
    // library to create a new instance of the media add form.
    // @see \Drupal\media_library\MediaLibraryUiBuilder::buildMediaTypeAddForm()
    $state = MediaLibraryState::fromRequest($this->getRequest());
    $state = $form_state->get('media_library_state');
    $state->remove('media_library_content');
    $state->set('_media_library_form_rebuild', TRUE);
    $library_ui = $this->libraryUiBuilder->buildUi($state);
+6 −0
Changes for core/modules/media_library/src/MediaLibraryUiBuilder.php: 6 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -306,6 +306,12 @@ protected function buildMediaLibraryView(MediaLibraryState $state) {

    $args = [$state->getSelectedTypeId()];

    // Make sure the state parameters are set in the request so the view can
    // pass the parameters along in the pager, filters etc.
    $request = $view_executable->getRequest();
    $request->query->add($state->all());
    $view_executable->setRequest($request);

    $view_executable->setDisplay($display_id);
    $view_executable->preExecute($args);
    $view_executable->execute($display_id);
+41 −13
Changes for core/modules/media_library/src/Plugin/Field/FieldWidget/MediaLibraryWidget.php: 41 added lines, 13 removed lines.
Original line number Diff line number Diff line
@@ -2,9 +2,10 @@

namespace Drupal\media_library\Plugin\Field\FieldWidget;

use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\SortArray;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
@@ -12,7 +13,6 @@
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Drupal\media\Entity\Media;
use Drupal\media_library\MediaLibraryUiBuilder;
use Drupal\media_library\MediaLibraryState;
@@ -395,23 +395,32 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
    $opener_id = static::$openerIdPrefix . $field_name . $id_suffix;

    $state = MediaLibraryState::create($opener_id, $allowed_media_type_ids, $selected_type_id, $remaining);
    $dialog_options = Json::encode(MediaLibraryUiBuilder::dialogOptions());

    // Add a button that will load the Media library in a modal using AJAX.
    $element['media_library_open_button'] = [
      '#type' => 'link',
      '#title' => $this->t('Add media'),
      '#type' => 'submit',
      '#value' => $this->t('Add media'),
      '#name' => $field_name . '-media-library-open-button' . $id_suffix,
      '#url' => $url = Url::fromRoute('media_library.ui', [], [
        'query' => $state->all(),
      ]),
      '#attributes' => [
        'class' => ['button', 'use-ajax', 'media-library-open-button'],
        'data-dialog-type' => 'modal',
        'data-dialog-options' => $dialog_options,
        'class' => [
          'media-library-open-button',
          'js-media-library-open-button',
        ],
      // Prevent errors in other widgets from preventing addition.
      '#limit_validation_errors' => $limit_validation_errors,
        // The jQuery UI dialog automatically moves focus to the first :tabbable
        // element of the modal, so we need to disable refocus on the button.
        'data-disable-refocus' => 'true',
      ],
      '#media_library_state' => $state,
      '#ajax' => [
        'callback' => [static::class, 'openMediaLibrary'],
        'progress' => [
          'type' => 'throbber',
          'message' => $this->t('Opening media library.'),
        ],
      ],
      '#submit' => [],
      // Allow the media library to be opened even if there are form errors.
      '#limit_validation_errors' => [],
      '#access' => $cardinality_unlimited || $remaining > 0,
    ];

@@ -526,6 +535,25 @@ public static function removeItem(array $form, FormStateInterface $form_state) {
    $form_state->setRebuild();
  }

  /**
   * AJAX callback to open the library modal.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   An AJAX response to open the media library.
   */
  public static function openMediaLibrary(array $form, FormStateInterface $form_state) {
    $triggering_element = $form_state->getTriggeringElement();
    $library_ui = \Drupal::service('media_library.ui_builder')->buildUi($triggering_element['#media_library_state']);
    $dialog_options = MediaLibraryUiBuilder::dialogOptions();
    return (new AjaxResponse())
      ->addCommand(new OpenModalDialogCommand($dialog_options['title'], $library_ui, $dialog_options));
  }

  /**
   * Validates that newly selected items can be added to the widget.
   *
+22 −22
Changes for core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php: 22 added lines, 22 removed lines.
Original line number Diff line number Diff line
@@ -204,7 +204,7 @@ public function testWidget() {
    $assert_session->pageTextContains('Empty types media');

    // Assert generic media library elements.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->pageTextContains('Add or select media');
    $this->assertFalse($assert_session->elementExists('css', '.media-library-select-all')->isVisible());
@@ -212,7 +212,7 @@ public function testWidget() {

    // Assert that the media type menu is available when more than 1 type is
    // configured for the field.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $menu = $assert_session->elementExists('css', '.media-library-menu');
    $this->assertTrue($menu->hasLink('Type One'));
@@ -224,7 +224,7 @@ public function testWidget() {

    // Assert that the media type menu is available when no types are configured
    // for the field. All types should be available in this case.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_empty_types_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_empty_types_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $menu = $assert_session->elementExists('css', '.media-library-menu');
    $this->assertTrue($menu->hasLink('Type One'));
@@ -236,7 +236,7 @@ public function testWidget() {

    // Assert that the media type menu is not available when only 1 type is
    // configured for the field.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_single_media_type"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_single_media_type"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->elementTextContains('css', '.media-library-selected-count', '0 of 1 item selected');
    // Select a media item, assert the hidden selection field contains the ID of
@@ -249,7 +249,7 @@ public function testWidget() {
    $page->find('css', '.ui-dialog-titlebar-close')->click();

    // Assert the menu links can be sorted through the widget configuration.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_twin_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_twin_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $links = $page->findAll('css', '.media-library-menu a');
    $link_titles = [];
@@ -270,7 +270,7 @@ public function testWidget() {
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->buttonExists('Hide row weights')->press();
    $this->drupalGet('node/add/basic_page');
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_twin_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_twin_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $link_titles = array_map(function ($link) {
      return $link->getText();
@@ -279,7 +279,7 @@ public function testWidget() {
    $page->find('css', '.ui-dialog-titlebar-close')->click();

    // Assert media is only visible on the tab for the related media type.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->pageTextContains('Dog');
    $assert_session->pageTextContains('Bear');
@@ -293,7 +293,7 @@ public function testWidget() {
    $page->find('css', '.ui-dialog-titlebar-close')->click();

    // Assert the exposed name filter of the view.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $session = $this->getSession();
    $session->getPage()->fillField('Name', 'Dog');
@@ -310,7 +310,7 @@ public function testWidget() {

    // Assert the media library contains header links to switch between the grid
    // and table display.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->elementExists('css', '.media-library-view .media-library-item--grid');
    $assert_session->elementNotExists('css', '.media-library-view .media-library-item--table');
@@ -368,7 +368,7 @@ public function testWidget() {

    // Assert the selection is persistent in the media library modal, and
    // the number of selected items is displayed correctly.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_twin_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_twin_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    // Assert the number of selected items is displayed correctly.
    $assert_session->elementExists('css', '.media-library-selected-count');
@@ -452,7 +452,7 @@ public function testWidget() {
    $assert_session->pageTextContains('Turtle');

    // Open the media library again and select another item.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_twin_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_twin_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $checkboxes = $page->findAll('css', '.media-library-view .js-click-to-select-checkbox input');
    $checkboxes[0]->click();
@@ -464,10 +464,10 @@ public function testWidget() {
    $assert_session->pageTextNotContains('Snake');

    // Assert we are not allowed to add more items to the field.
    $assert_session->elementNotExists('css', '.media-library-open-button[href*="field_twin_media"]');
    $assert_session->elementNotExists('css', '.media-library-open-button[name^="field_twin_media"]');

    // Assert the selection is cleared when the modal is closed.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    // Nothing is selected yet.
    $this->assertFalse($checkboxes[0]->isChecked());
@@ -487,7 +487,7 @@ public function testWidget() {
    $this->assertFalse($checkboxes[3]->isChecked());
    // Close the dialog, reopen it and assert not is selected again.
    $page->find('css', '.ui-dialog-titlebar-close')->click();
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $checkboxes = $page->findAll('css', '.media-library-view .js-click-to-select-checkbox input');
    $this->assertFalse($checkboxes[0]->isChecked());
@@ -521,7 +521,7 @@ public function testWidget() {
    $assert_session->pageTextNotContains('Horse');
    $assert_session->pageTextContains('Turtle');
    $assert_session->pageTextNotContains('Snake');
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->pageTextContains('Add or select media');
    // Select all media items of type one (should also contain Dog, again).
@@ -569,7 +569,7 @@ public function testWidgetAnonymous() {
    $this->drupalGet('node/add/basic_page');

    // Add to the unlimited cardinality field.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();

    // Select the first media item (should be Dog).
@@ -624,7 +624,7 @@ public function testWidgetUpload() {

    // Visit a node create page and open the media library.
    $this->drupalGet('node/add/basic_page');
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_twin_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_twin_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->pageTextContains('Add or select media');

@@ -658,7 +658,7 @@ public function testWidgetUpload() {
    $file_system = $this->container->get('file_system');

    // Add to the twin media field.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_twin_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_twin_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->pageTextContains('Add or select media');

@@ -720,7 +720,7 @@ public function testWidgetUpload() {
    $assert_session->pageTextContains($png_image->filename);

    // Also make sure that we can upload to the unlimited cardinality field.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->pageTextContains('Add or select media');

@@ -775,7 +775,7 @@ public function testWidgetUpload() {
    $assert_session->pageTextContains('Unlimited Cardinality Image');

    // Verify we can only upload the files allowed by the media type.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_twin_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_twin_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->pageTextContains('Add or select media');
    $page->clickLink('Type Four');
@@ -835,7 +835,7 @@ public function testWidgetOEmbed() {
    $this->drupalGet('node/add/basic_page');

    // Add to the unlimited media field.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $assert_session->elementExists('css', '.media-library-open-button[name^="field_unlimited_media"]')->click();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->pageTextContains('Add or select media');

@@ -880,7 +880,7 @@ public function testWidgetOEmbed() {

    // Open the media library again for the unlimited field and go to the tab
    // for media type five.
    $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]')->click();
    $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 Five');