diff -u b/core/composer.json b/core/composer.json --- b/core/composer.json +++ b/core/composer.json @@ -120,7 +120,6 @@ "drupal/locale": "self.version", "drupal/minimal": "self.version", "drupal/media": "self.version", - "drupal/media_library": "self.version", "drupal/menu_link_content": "self.version", "drupal/menu_ui": "self.version", "drupal/migrate": "self.version", @@ -134,6 +133,7 @@ "drupal/locale": "self.version", "drupal/minimal": "self.version", "drupal/media": "self.version", + "drupal/media_library": "self.version", "drupal/menu_link_content": "self.version", "drupal/menu_ui": "self.version", "drupal/migrate": "self.version", diff -u b/core/modules/media_library/config/install/views.view.media_library.yml b/core/modules/media_library/config/install/views.view.media_library.yml --- b/core/modules/media_library/config/install/views.view.media_library.yml +++ b/core/modules/media_library/config/install/views.view.media_library.yml @@ -8,7 +8,7 @@ - media_library - user id: media_library -label: Media +label: Media Library module: views description: '' tag: '' @@ -25,7 +25,7 @@ access: type: perm options: - perm: 'view media' + perm: 'access media overview' cache: type: tag options: { } @@ -330,7 +330,7 @@ entity_type: media entity_field: created plugin_id: date - title: Media + title: 'Media' header: { } footer: { } empty: { } @@ -390,153 +390,9 @@ tags: - 'config:core.entity_view_display.media.audio.default' - 'config:core.entity_view_display.media.file.default' + - 'config:core.entity_view_display.media.file.media_library' - 'config:core.entity_view_display.media.image.default' - - 'config:core.entity_view_display.media.video.default' - bundle_page: - display_plugin: page - id: bundle_page - display_title: 'Bundle Page' - position: 2 - display_options: - display_extenders: { } - path: admin/content/media/%bundle - display_description: '' - cache_metadata: - max-age: 0 - contexts: - - 'languages:language_interface' - - url - - url.query_args - - 'url.query_args:sort_by' - - user.permissions - tags: - - 'config:core.entity_view_display.media.audio.default' - - 'config:core.entity_view_display.media.file.default' - - 'config:core.entity_view_display.media.image.default' - - 'config:core.entity_view_display.media.video.default' - embed: - display_plugin: embed - id: embed - display_title: Embed - position: 4 - display_options: - display_extenders: { } - fields: - media_select_media: - id: media_select_media - table: media - field: media_select_media - relationship: none - group_type: group - admin_label: '' - label: '' - exclude: false - alter: - alter_text: false - text: '' - make_link: false - path: '' - absolute: false - external: false - replace_spaces: false - path_case: none - trim_whitespace: false - alt: '' - rel: '' - link_class: '' - prefix: '' - suffix: '' - target: '' - nl2br: false - max_length: 0 - word_boundary: true - ellipsis: true - more_link: false - more_link_text: '' - more_link_path: '' - strip_tags: false - trim: false - preserve_tags: '' - html: false - element_type: '' - element_class: media-library-item-checkbox - element_label_type: '' - element_label_class: '' - element_label_colon: false - element_wrapper_type: '' - element_wrapper_class: '' - element_default_classes: true - empty: '' - hide_empty: false - empty_zero: false - hide_alter_empty: true - entity_type: media - plugin_id: select_media - rendered_entity: - id: rendered_entity - table: media - field: rendered_entity - relationship: none - group_type: group - admin_label: '' - label: '' - exclude: false - alter: - alter_text: false - text: '' - make_link: false - path: '' - absolute: false - external: false - replace_spaces: false - path_case: none - trim_whitespace: false - alt: '' - rel: '' - link_class: '' - prefix: '' - suffix: '' - target: '' - nl2br: false - max_length: 0 - word_boundary: true - ellipsis: true - more_link: false - more_link_text: '' - more_link_path: '' - strip_tags: false - trim: false - preserve_tags: '' - html: false - element_type: '' - element_class: media-library-item-content - element_label_type: '' - element_label_class: '' - element_label_colon: false - element_wrapper_type: '' - element_wrapper_class: '' - element_default_classes: true - empty: '' - hide_empty: false - empty_zero: false - hide_alter_empty: true - view_mode: media_library - entity_type: media - plugin_id: rendered_entity - defaults: - fields: false - cache_metadata: - max-age: 0 - contexts: - - 'languages:language_interface' - - url - - url.query_args - - 'url.query_args:sort_by' - - user.permissions - tags: - - 'config:core.entity_view_display.media.audio.default' - - 'config:core.entity_view_display.media.file.default' - - 'config:core.entity_view_display.media.image.default' + - 'config:core.entity_view_display.media.image.media_library' - 'config:core.entity_view_display.media.video.default' page: display_plugin: page @@ -568,144 +424,5 @@ - 'config:core.entity_view_display.media.file.default' + - 'config:core.entity_view_display.media.file.media_library' - 'config:core.entity_view_display.media.image.default' - - 'config:core.entity_view_display.media.video.default' - widget: - display_plugin: page - id: widget - display_title: Widget - position: 4 - display_options: - display_extenders: { } - fields: - media_select_media: - id: media_select_media - table: media - field: media_select_media - relationship: none - group_type: group - admin_label: '' - label: '' - exclude: false - alter: - alter_text: false - text: '' - make_link: false - path: '' - absolute: false - external: false - replace_spaces: false - path_case: none - trim_whitespace: false - alt: '' - rel: '' - link_class: '' - prefix: '' - suffix: '' - target: '' - nl2br: false - max_length: 0 - word_boundary: true - ellipsis: true - more_link: false - more_link_text: '' - more_link_path: '' - strip_tags: false - trim: false - preserve_tags: '' - html: false - element_type: '' - element_class: media-library-item-checkbox - element_label_type: '' - element_label_class: '' - element_label_colon: false - element_wrapper_type: '' - element_wrapper_class: '' - element_default_classes: true - empty: '' - hide_empty: false - empty_zero: false - hide_alter_empty: true - entity_type: media - plugin_id: select_media - rendered_entity: - id: rendered_entity - table: media - field: rendered_entity - relationship: none - group_type: group - admin_label: '' - label: '' - exclude: false - alter: - alter_text: false - text: '' - make_link: false - path: '' - absolute: false - external: false - replace_spaces: false - path_case: none - trim_whitespace: false - alt: '' - rel: '' - link_class: '' - prefix: '' - suffix: '' - target: '' - nl2br: false - max_length: 0 - word_boundary: true - ellipsis: true - more_link: false - more_link_text: '' - more_link_path: '' - strip_tags: false - trim: false - preserve_tags: '' - html: false - element_type: '' - element_class: media-library-item-content - element_label_type: '' - element_label_class: '' - element_label_colon: false - element_wrapper_type: '' - element_wrapper_class: '' - element_default_classes: true - empty: '' - hide_empty: false - empty_zero: false - hide_alter_empty: true - view_mode: media_library - entity_type: media - plugin_id: rendered_entity - defaults: - fields: false - header: false - display_description: '' - path: admin/media_field_widget - header: - area: - id: area - table: views - field: area - relationship: none - group_type: group - admin_label: '' - empty: false - tokenize: false - content: - value: 'Add New Media' - format: full_html - plugin_id: text - cache_metadata: - max-age: 0 - contexts: - - 'languages:language_interface' - - url - - url.query_args - - 'url.query_args:sort_by' - - user.permissions - tags: - - 'config:core.entity_view_display.media.audio.default' - - 'config:core.entity_view_display.media.file.default' - - 'config:core.entity_view_display.media.image.default' + - 'config:core.entity_view_display.media.image.media_library' - 'config:core.entity_view_display.media.video.default' diff -u b/core/modules/media_library/css/media_library.css b/core/modules/media_library/css/media_library.css --- b/core/modules/media_library/css/media_library.css +++ b/core/modules/media_library/css/media_library.css @@ -2,7 +2,7 @@ * @file media_library.view.css */ -#views-form-media-library-page, *[id^='views-form-media-library-widget-'], .media-library-selection { +#views-form-media-library-page { display: flex; flex-wrap: wrap; align-content: space-between; @@ -31,21 +31,21 @@ transition: border-color .2s, outline-color .2s; } -.media-library-item .field { - display: none; -} - .media-library-item .field--name-thumbnail { - display: block; + background-color: #989898; + border-bottom: 2px solid #ebebeb; } .media-library-item .field--name-thumbnail img { - width: 100%; - height: auto; + min-width: 180px; + min-height: 180px; + object-fit: cover; } -.media-library-item.media-library-item-in-widget, .media-library-item.is-hover.media-library-item-in-widget { - cursor: move; +.media-library-item .media-library-item-preview { + width: 180px; + height: 180px; + overflow: hidden; } .media-library-item.checked { @@ -124,21 +124,6 @@ display: inline-block; } -.media-library-item .field--name-thumbnail { - background-color: #989898; - border-bottom: 2px solid #ebebeb; - height: 180px; - width: 180px; - overflow: hidden; -} - -.media-library-item .field--name-thumbnail img { - height: auto; - min-height: 180px; - min-width: 180px; - width: auto; -} - .media-library-item-name { font-size: 14px; text-overflow: ellipsis; @@ -160,33 +144,0 @@ - -.media-library-item .media-library-item-remove { - position: absolute; - z-index: 1; - top: 0; - right: 0; - width: 24px; - height: 24px; - margin: 5px; - padding: 0; - background: url('../../../misc/icons/787878/ex.svg') #ffffff center no-repeat; - background-size: 16px 16px; - border: 1px solid #ccc; - border-radius: 20px; - color: transparent; - text-shadow: none; - opacity: 0; - transition: opacity .2s; -} - -.media-library-item .media-library-item-remove:hover, -.media-library-item .media-library-item-remove:focus, -.media-library-item .media-library-item-remove.button:disabled { - background: url('../../../misc/icons/787878/ex.svg') #ffffff center no-repeat; - background-size: 16px 16px; - color: transparent; - opacity: 1; - text-shadow: none; -} - -.media-library-open-button { - margin-top: 10px; -} diff -u b/core/modules/media_library/js/media_library.view.js b/core/modules/media_library/js/media_library.view.js --- b/core/modules/media_library/js/media_library.view.js +++ b/core/modules/media_library/js/media_library.view.js @@ -1,42 +1,31 @@ /** - * @file media_library.view.js - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal) { "use strict"; - // Locally-scoped variable that stores the current View selection. We track - // this in a variable as users may click a media item and then re-load the - // View with AJAX (filters, pagers, sorts, etc.), which will lose what is - // currently selected in the bulk form. This could likely be back-ported to - // core. - var MediaLibrarySelectedEntities = {}; - - /** - * Allows users to click on hidden Views select checkboxes by clicking on the - * media item (which is also a Views row). - */ Drupal.behaviors.MediaLibraryCheckboxes = { - attach: function (context) { - $('.media-library-item .field--name-thumbnail', context).once('media-library-checkbox').on('click', function (event) { - // Links inside the rendered media item should not be click-able. + attach: function attach(context) { + $('.media-library-item .media-library-item-preview', context).once('media-library-checkbox').on('click', function (event) { event.preventDefault(); - // Click the hidden checkbox when the media item is clicked. + var $input = $(this).parents('.media-library-item').find('.media-library-item-checkbox input'); $input.prop('checked', !$input.prop('checked')); if ($input.prop('checked')) { $(this).parents('.media-library-item').addClass('checked'); - } - else { + } else { $(this).parents('.media-library-item').removeClass('checked'); } if ($('.media-library-item.checked').length) { $('#edit-header').show(); $('.view-content #edit-actions').show(); - } - else { + } else { $('#edit-header').hide(); $('.view-content #edit-actions').hide(); } @@ -49,111 +38,23 @@ - /** - * Allows users to toggle metadata on media items. - */ Drupal.behaviors.MediaLibraryMetadataToggle = { - attach: function (context) { - // Add the toggle when javascript is available + attach: function attach(context) { $('.media-library-item-attributes', context).after(''); - $('.media-library-item-toggle').on('click', function () { + $('.media-library-item-toggle').once('media-library-toggle').on('click', function () { if ($(this).parents('.media-library-item').hasClass('expanded')) { $(this).parents('.media-library-item').removeClass('expanded'); - } - else { + } else { $(this).parents('.media-library-item').addClass('expanded'); } }); } }; - /** - * Adds hover effect to media items. - */ Drupal.behaviors.MediaLibraryHover = { - attach: function (context) { - $('.media-library-item .field--name-thumbnail', context).once('media-library-item').on('mouseover', function (){ + attach: function attach(context) { + $('.media-library-item .media-library-item-preview', context).once('media-library-item').on('mouseover', function () { $(this).parents('.media-library-item').addClass('is-hover'); - }).on('mouseout', function(){ + }).on('mouseout', function () { $(this).parents('.media-library-item').removeClass('is-hover'); }); } }; - - /** - * Persists bulk and select form selections across AJAX View re-renders. - */ - Drupal.behaviors.MediaLibraryPersistentSelection = { - attach: function (context) { - // For each View on the page, store the dom-id as a data attribute so - // that we can easily access it later. This is normally only stored in a - // class. - $('[class*="js-view-dom-id-"]', context).once('set-dom-id-data-attribute').each(function () { - var element = $(this); - var classes = $(this).attr('class').split(/\s+/); - $(classes).each(function (i, class_name) { - var dom_id = class_name.match(new RegExp('^js-view-dom-id-(.*)$')); - if (dom_id) { - element.attr('data-views-dom-id', dom_id[1]); - if (!MediaLibrarySelectedEntities[dom_id[1]]) { - MediaLibrarySelectedEntities[dom_id[1]] = []; - } - } - }); - }); - - // Check/uncheck checkboxes in the view based on the selected media. - $('.media-library-item-checkbox input', context).once('data-media-select').each(function (i, element) { - $(this).on('change', function () { - var checked = $(this).prop('checked'); - var views_dom_id = $(this).closest('[data-views-dom-id]').data('views-dom-id'); - var entity = $(this).val(); - if (checked) { - MediaLibrarySelectedEntities[views_dom_id].push(entity); - } - else { - MediaLibrarySelectedEntities[views_dom_id] = $(MediaLibrarySelectedEntities[views_dom_id]).filter(function (i, value) { - return !(entity == value); - }); - } - }); - }); - } - }; - - /** - * Attaches extra POST data when the Views bulk form is submitted, to ensure - * that selections that may be off-screen persist during the submit process. - */ - Drupal.behaviors.MediaLibraryViewsSubmit = { - attach: function (context, settings) { - $('[data-views-dom-id]', context).once('media-library-checkbox-submit').each(function () { - var $view = $(this); - var views_dom_id = $(this).data('views-dom-id'); - $.each(MediaLibrarySelectedEntities[views_dom_id], function(index, items) { - $view.find('input[value="' + items + '"]').prop('checked', true); - $view.find('input[value="' + items + '"]').closest('.media-library-item').addClass('checked'); - }); - - // Propagate all selected entities to the form submission. - $view.find('[data-media-select-submit]').each(function () { - var button = $(this); - $.each(Drupal.ajax.instances, function () { - if (this && $(this.element).is(button)) { - if (settings && settings.views && settings.views.ajaxViews) { - var ajaxViews = settings.views.ajaxViews; - for (var i in ajaxViews) { - var ajaxViewsInstance = Drupal.views.instances[i]; - if (ajaxViewsInstance.settings.view_dom_id == views_dom_id) { - this.submit = $.extend(this.submit, ajaxViewsInstance.settings, { - selected_entities: MediaLibrarySelectedEntities[views_dom_id], - media_library_input: settings.media_library.media_library_inputs[views_dom_id] - }); - } - } - } - } - }); - }); - }); - } - }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file reverted: --- b/core/modules/media_library/js/media_library.widget.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @file media_library.widget.js - */ - -(function ($, Drupal) { - - "use strict"; - - /** - * Provides custom JS behaviors related to the media library field widget. - */ - Drupal.behaviors.MediaLibraryWidget = { - attach: function (context) { - $('.media-library-selection', context).sortable({ - tolerance: 'pointer', - stop: function(event, ui) { - // Update all the hidden "weight" fields. - $(event.target).children().each(function (index) { - $(this).find('.media-library-item-weight').val(index); - }); - } - }); - } - }; - -})(jQuery, Drupal); diff -u b/core/modules/media_library/media_library.info.yml b/core/modules/media_library/media_library.info.yml --- b/core/modules/media_library/media_library.info.yml +++ b/core/modules/media_library/media_library.info.yml @@ -1,6 +1,6 @@ name: 'Media library' type: module -description: 'Provides a library for adding and re-using Media Items.' +description: 'Provides a library for re-using Media Items.' package: Core (Experimental) version: VERSION core: 8.x diff -u b/core/modules/media_library/media_library.libraries.yml b/core/modules/media_library/media_library.libraries.yml --- b/core/modules/media_library/media_library.libraries.yml +++ b/core/modules/media_library/media_library.libraries.yml @@ -16,13 +16,2 @@ - - core/drupal.dialog.ajax - core/jquery - core/jquery.once - -widget: - version: VERSION - js: - js/media_library.widget.js: {} - dependencies: - - core/drupal - - core/jquery - - core/jquery.ui.sortable - - media_library/style diff -u b/core/modules/media_library/media_library.module b/core/modules/media_library/media_library.module --- b/core/modules/media_library/media_library.module +++ b/core/modules/media_library/media_library.module @@ -35,15 +35,12 @@ if ($variables['view_mode'] === 'media_library') { /** @var \Drupal\media\MediaInterface $media */ $media = $variables['media']; - /** @var \Drupal\user\UserInterface $user */ - if ($user = $media->getRevisionUser()) { - $variables['author_info'] = [ - '#markup' => t('Created by %author', ['%author' => $user->getDisplayName()]), - ]; - } $variables['created_ago'] = [ '#markup' => _media_library_pretty_time($media->getCreatedTime()), ]; + $variables['url'] = $media->toUrl('canonical', [ + 'language' => $media->language(), + ]); } } reverted: --- b/core/modules/media_library/src/Plugin/Field/FieldWidget/MediaLibraryWidget.php +++ /dev/null @@ -1,366 +0,0 @@ -entityTypeManager = $entity_type_manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $plugin_id, - $plugin_definition, - $configuration['field_definition'], - $configuration['settings'], - $configuration['third_party_settings'], - $container->get('entity_type.manager') - ); - } - - /** - * {@inheritdoc} - */ - public static function isApplicable(FieldDefinitionInterface $field_definition) { - return $field_definition->getSetting('target_type') === 'media'; - } - - /** - * {@inheritdoc} - */ - public function form(FieldItemListInterface $items, array &$form, FormStateInterface $form_state, $get_delta = NULL) { - $field_name = $this->fieldDefinition->getName(); - $parents = $form['#parents']; - - // Load the items for form rebuilds from the field state as they might not be - // in $form_state['values'] because of validation limitations. - $field_state = static::getWidgetState($parents, $field_name, $form_state); - if ($field_state && isset($field_state['items'])) { - usort($field_state['items'], [SortArray::class, 'sortByWeightElement']); - $items->setValue($field_state['items']); - } - - $build = parent::form($items, $form, $form_state, $get_delta); - - return $build; - } - - /** - * {@inheritdoc} - */ - public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { - /** @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $items */ - $referenced_entities = $items->referencedEntities(); - $view_builder = $this->entityTypeManager->getViewBuilder($this->getFieldSetting('target_type')); - $field_name = $this->fieldDefinition->getName(); - $parents = $form['#parents']; - $id_suffix = '-' . implode('-', $parents); - $wrapper_id = $field_name . '-media-library-wrapper' . $id_suffix; - - $element += [ - '#type' => 'fieldset', - '#cardinality' => $this->fieldDefinition->getFieldStorageDefinition()->getCardinality(), - 'selection' => [ - '#type' => 'container', - '#attributes' => [ - 'class' => 'media-library-selection', - ], - ], - '#attributes' => [ - 'id' => $wrapper_id, - 'class' => ['media-library-wrapper'], - ], - ]; - - if (empty($referenced_entities)) { - $element['empty_selection'] = [ - '#markup' => $this->t('
No media selected.
'), - ]; - } - else { - foreach ($referenced_entities as $delta => $media_item) { - $element['selection'][$delta] = [ - '#type' => 'container', - '#attributes' => [ - 'class' => ['media-library-item', 'media-library-item-in-widget'], - ], - 'preview' => [ - '#type' => 'container', - 'view' => $view_builder->view($media_item, 'media_library'), - '#attached' => [ - 'library' => ['media_library/widget'], - ], - 'remove_button' => [ - '#type' => 'submit', - '#media_library_remove_delta' => $delta, - '#name' => $field_name . '-' . $delta . '-media-library-remove-button' . $id_suffix, - '#value' => $this->t('Remove'), - '#attributes' => [ - 'class' => ['media-library-item-remove'], - ], - '#ajax' => [ - 'callback' => [static::class, 'updateWidget'], - 'wrapper' => $wrapper_id, - ], - '#submit' => [[static::class, 'removeItem']], - '#limit_validation_errors' => [array_merge($form['#parents'], [$field_name])], - ], - ], - 'target_id' => [ - '#type' => 'hidden', - '#value' => $media_item->id(), - ], - // This hidden value is set by JS when items are re-sorted. - 'weight' => [ - '#type' => 'hidden', - '#default_value' => $delta, - '#attributes' => [ - 'class' => ['media-library-item-weight'], - ], - ], - ]; - } - } - - // @todo We use a use-ajax link here as it is the only way we've seen - // contextual filters work when using a view in a modal. Unfortunately - // this only works the first time you open the modal - opening it twice - // in one page load breaks Views AJAX. - $element['media_library_open_container'] = [ - '#type' => 'container', - 'media_library_open_button' => [ - '#type' => 'link', - '#title' => $this->t('Add Media'), - '#name' => $field_name . '-media-library-open-button' . $id_suffix, - '#url' => Url::fromRoute('view.media_library.widget', [], [ - 'query' => ['media_library_input' => $field_name . $id_suffix], - ]), - '#attributes' => [ - 'class' => ['button', 'use-ajax', 'media-library-open-button'], - 'data-dialog-type' => 'modal', - 'data-dialog-options' => json_encode([ - 'height' => '75%', - 'width' => '75%', - 'title' => $this->t('Media library'), - ]), - ], - '#limit_validation_errors' => [array_merge($parents, [$field_name])], - ], - ]; - - // Add a hidden textfield to the form, which is used by the select_media - // Views field to pass values from the modal to the widget. This is similar - // to how the EntityReferenceAutocompleteWidget stores values. - $element['media_library_selection'] = [ - '#type' => 'textfield', - '#attributes' => [ - 'data-media-library-input-id' => $field_name . $id_suffix, - 'class' => ['visually-hidden'], - ], - ]; - - $element['media_library_update_widget'] = [ - '#type' => 'submit', - '#value' => $this->t('Update widget'), - '#name' => $field_name . '-media-library-update-button' . $id_suffix, - '#ajax' => [ - 'callback' => [static::class, 'updateWidget'], - 'wrapper' => $wrapper_id, - ], - '#attributes' => [ - 'data-media-library-submit-id' => $field_name . $id_suffix, - 'class' => ['visually-hidden', 'media-library-update-button'], - ], - '#submit' => [[static::class, 'updateItems']], - '#limit_validation_errors' => [array_merge($parents, [$field_name])], - ]; - - return $element; - } - - /** - * {@inheritdoc} - */ - public function errorElement(array $element, ConstraintViolationInterface $error, array $form, FormStateInterface $form_state) { - return isset($element['target_id']) ? $element['target_id'] : FALSE; - } - - /** - * {@inheritdoc} - */ - public function massageFormValues(array $values, array $form, FormStateInterface $form_state) { - if (isset($values['selection'])) { - usort($values['selection'], [SortArray::class, 'sortByWeightElement']); - return $values['selection']; - } - else { - return []; - } - } - - /** - * AJAX callback to update the widget when the selection changes. - * - * @param array $form - * The form array. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * The form state. - * - * @return array - * An array representing the updated widget. - */ - public static function updateWidget($form, FormStateInterface $form_state) { - $triggering_element = $form_state->getTriggeringElement(); - $length = isset($triggering_element['#media_library_remove_delta']) ? -4 : -1; - $parents = $triggering_element['#array_parents']; - $parents = array_slice($parents, 0, $length); - $element = NestedArray::getValue($form, $parents); - // Always clear the textfield selection to prevent duplicate additions. - $element['media_library_selection']['#value'] = ''; - return $element; - } - - /** - * Submit callback for remove buttons. - * - * @param array $form - * The form array. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * The form state. - */ - public static function removeItem($form, FormStateInterface $form_state) { - $triggering_element = $form_state->getTriggeringElement(); - - $parents = $triggering_element['#array_parents']; - $parents = array_slice($parents, 0, -4); - $element = NestedArray::getValue($form, $parents); - $field_name = $element['#field_name']; - $parents = $element['#field_parents']; - $delta = $triggering_element['#media_library_remove_delta']; - - // Find and remove correct entity. - $path = $element['#parents']; - $values = NestedArray::getValue($form_state->getValues(), $path); - $field_state = static::getWidgetState($parents, $field_name, $form_state); - if (isset($values['selection'])) { - if (isset($values['selection'][$delta])) { - array_splice($values['selection'], $delta, 1); - $field_state['items'] = $values['selection']; - $field_state['items_count'] = count($field_state['items']); - } - } - $form_state->setValue($field_name, $values); - static::setWidgetState($parents, $field_name, $form_state, $field_state); - - // Rebuild form. - $form_state->setRebuild(); - } - - /** - * Updates the field state based on the form state and sets the form rebuild. - * - * @param array $form - * The form array. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * The form state. - */ - public static function updateItems($form, FormStateInterface $form_state) { - $button = $form_state->getTriggeringElement(); - - // Go one level up in the form, to the widgets container. - $element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1)); - $field_name = $element['#field_name']; - $parents = $element['#field_parents']; - $field_state = static::getWidgetState($parents, $field_name, $form_state); - - // Get the new media ids passed to our hidden button. - $values = $form_state->getValues(); - $path = $element['#parents']; - $value = NestedArray::getValue($values, $path); - $selection = isset($value['selection']) ? $value['selection'] : []; - - $field_state['items'] = $selection; - - if (!empty($value['media_library_selection'])) { - $ids = explode(',', $value['media_library_selection']); - /** @var \Drupal\media\MediaInterface[] $media */ - $media = Media::loadMultiple($ids); - - // Append the provided Media to the existing selection. - $cardinality_unlimited = ($element['#cardinality'] === FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); - foreach ($media as $media_item) { - if ($cardinality_unlimited || (count($field_state['items']) < $element['#cardinality'])) { - if ($media && $media_item->access('view')) { - $field_state['items'][] = [ - 'target_id' => $media_item->id(), - ]; - } - } - } - } - - $field_state['items_count'] = count($field_state['items']); - static::setWidgetState($parents, $field_name, $form_state, $field_state); - - $form_state->setRebuild(); - } - -} reverted: --- b/core/modules/media_library/src/Plugin/views/field/SelectMedia.php +++ /dev/null @@ -1,91 +0,0 @@ -options['id']])) { - foreach (Element::children($form[$this->options['id']]) as $index) { - $item = &$form[$this->options['id']][$index]; - $item['#attributes']['data-media-select'] = TRUE; - } - } - if (isset($form['actions']['submit'])) { - $form['actions']['submit']['#attributes']['data-media-select-submit'] = TRUE; - $form['actions']['submit']['#ajax']['url'] = Url::fromRoute('