diff --git a/core/misc/cspell/dictionary.txt b/core/misc/cspell/dictionary.txt index e2aee906ebe1ab769117a8e6524c0297c8f1273f..30a2064e2728d154f34eb788751e9f13c0fad39f 100644 --- a/core/misc/cspell/dictionary.txt +++ b/core/misc/cspell/dictionary.txt @@ -366,6 +366,7 @@ pickable pingback placeholdered placeholdering +playsinline plusthick porterstemmer postcondition diff --git a/core/modules/file/config/schema/file.schema.yml b/core/modules/file/config/schema/file.schema.yml index e193063740b7334830647433466f0f78c2b2c2b6..531ef0723b456280c569e008920aa001f97424c9 100644 --- a/core/modules/file/config/schema/file.schema.yml +++ b/core/modules/file/config/schema/file.schema.yml @@ -133,6 +133,9 @@ field.formatter.settings.file_video: muted: type: boolean label: 'Muted' + playsinline: + type: boolean + label: 'Plays inline' width: type: integer label: 'Width' diff --git a/core/modules/file/file.module b/core/modules/file/file.module index 120d553c5c6dd943642a94aa5e2f25d83bcb3ca6..f3297f7ba6330ccb5fb5694371a0ae67fac1c4d1 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -23,6 +23,7 @@ use Drupal\Core\Template\Attribute; use Drupal\file\FileInterface; use Drupal\file\IconMimeTypes; +use Drupal\file\Plugin\Field\FieldFormatter\FileVideoFormatter; use Drupal\file\Upload\FileUploadHandlerInterface; use Drupal\file\Upload\FormUploadedFile; @@ -765,3 +766,12 @@ function file_system_settings_submit(array &$form, FormStateInterface $form_stat ->set('filename_sanitization', $form_state->getValue('filename_sanitization')); $config->save(); } + +/** + * Implements hook_ENTITY_TYPE_presave(). + */ +function file_file_video_presave(FileVideoFormatter $formatter): void { + if ($formatter->getSetting('playsinline') === NULL) { + $formatter->setSetting('playsinline', FALSE); + } +} diff --git a/core/modules/file/file.post_update.php b/core/modules/file/file.post_update.php index 1c40f237edd1b7f69d9e2f3cc69318c0281d9f2b..b7ecaabff8ae4e744e4f09eb45dc8177e76dd3fc 100644 --- a/core/modules/file/file.post_update.php +++ b/core/modules/file/file.post_update.php @@ -5,6 +5,10 @@ * Post update functions for File. */ +use Drupal\Core\Config\Entity\ConfigEntityUpdater; +use Drupal\Core\Entity\Display\EntityViewDisplayInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * Implements hook_removed_post_updates(). */ @@ -15,3 +19,23 @@ function file_removed_post_updates(): array { 'file_post_update_add_default_filename_sanitization_configuration' => '11.0.0', ]; } + +/** + * Adds a value for the 'playsinline' setting of the 'file_video' formatter. + */ +function file_post_update_add_playsinline(array &$sandbox = []): ?TranslatableMarkup { + /** @var \Drupal\Core\Config\Entity\ConfigEntityUpdater $config_entity_updater */ + $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class); + return $config_entity_updater->update($sandbox, 'entity_view_display', function (EntityViewDisplayInterface $display) { + $needs_update = FALSE; + $components = $display->getComponents(); + foreach ($components as $name => $component) { + if (isset($component['type']) && $component['type'] === 'file_video') { + $needs_update = TRUE; + $component['settings']['playsinline'] = FALSE; + $display->setComponent($name, $component); + } + } + return $needs_update; + }); +} diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/FileVideoFormatter.php b/core/modules/file/src/Plugin/Field/FieldFormatter/FileVideoFormatter.php index 41966203a374447cbd63e34767053f42fbe071b3..4cf055bccb8fa880ecbe9ef86f2808f1291b7f20 100644 --- a/core/modules/file/src/Plugin/Field/FieldFormatter/FileVideoFormatter.php +++ b/core/modules/file/src/Plugin/Field/FieldFormatter/FileVideoFormatter.php @@ -32,6 +32,7 @@ public static function getMediaType() { public static function defaultSettings() { return [ 'muted' => FALSE, + 'playsinline' => FALSE, 'width' => 640, 'height' => 480, ] + parent::defaultSettings(); @@ -47,6 +48,11 @@ public function settingsForm(array $form, FormStateInterface $form_state) { '#type' => 'checkbox', '#default_value' => $this->getSetting('muted'), ], + 'playsinline' => [ + '#title' => $this->t('Plays Inline'), + '#type' => 'checkbox', + '#default_value' => $this->getSetting('playsinline'), + ], 'width' => [ '#type' => 'number', '#title' => $this->t('Width'), @@ -76,6 +82,7 @@ public function settingsForm(array $form, FormStateInterface $form_state) { public function settingsSummary() { $summary = parent::settingsSummary(); $summary[] = $this->t('Muted: %muted', ['%muted' => $this->getSetting('muted') ? $this->t('yes') : $this->t('no')]); + $summary[] = $this->t('Plays Inline: %playsinline', ['%playsinline' => $this->getSetting('playsinline') ? $this->t('yes') : $this->t('no')]); if ($width = $this->getSetting('width')) { $summary[] = $this->t('Width: %width pixels', [ @@ -96,7 +103,7 @@ public function settingsSummary() { * {@inheritdoc} */ protected function prepareAttributes(array $additional_attributes = []) { - $attributes = parent::prepareAttributes(['muted']); + $attributes = parent::prepareAttributes(['muted', 'playsinline']); if (($width = $this->getSetting('width'))) { $attributes->setAttribute('width', $width); } diff --git a/core/modules/file/tests/fixtures/update/file_post_update_playsinline-3046152.php b/core/modules/file/tests/fixtures/update/file_post_update_playsinline-3046152.php new file mode 100644 index 0000000000000000000000000000000000000000..876e33ccbb264814d1e31453842e79729b921b82 --- /dev/null +++ b/core/modules/file/tests/fixtures/update/file_post_update_playsinline-3046152.php @@ -0,0 +1,23 @@ +<?php + +/** + * @file + * Fixture file to test file_post_update_add_playsinline(). + * + * @see https://www.drupal.org/project/drupal/issues/3046152 + * @see \Drupal\Tests\file\Functional\Formatter\FileVideoFormatterUpdateTest + * @see \file_post_update_add_playsinline() + */ + +use Drupal\Component\Serialization\Yaml; +use Drupal\Core\Database\Database; + +$display = Yaml::decode(file_get_contents(__DIR__ . '/post_update_playsinline-3046152-node-article.yml')); + +$db = Database::getConnection(); +$db->update('config') + ->fields([ + 'data' => serialize($display), + ]) + ->condition('name', 'core.entity_view_display.node.article.default') + ->execute(); diff --git a/core/modules/file/tests/fixtures/update/post_update_playsinline-3046152-node-article.yml b/core/modules/file/tests/fixtures/update/post_update_playsinline-3046152-node-article.yml new file mode 100644 index 0000000000000000000000000000000000000000..8657e1c7667d0eef63695ca26aadb0ca8bb8328a --- /dev/null +++ b/core/modules/file/tests/fixtures/update/post_update_playsinline-3046152-node-article.yml @@ -0,0 +1,80 @@ +# cspell:ignore autoplay +uuid: 93ccb838-5462-45ee-862a-988b9bdc6e0f +langcode: en +status: true +dependencies: + config: + - core.entity_view_display.comment.comment.default + - field.field.node.article.body + - field.field.node.article.comment + - field.field.node.article.field_image + - field.field.node.article.field_tags + - field.field.node.article.field_video + - image.style.wide + - node.type.article + module: + - comment + - file + - image + - text + - user +id: node.article.default +targetEntityType: node +bundle: article +mode: default +content: + body: + type: text_default + label: hidden + settings: { } + third_party_settings: { } + weight: 0 + region: content + comment: + type: comment_default + label: above + settings: + view_mode: default + pager_id: 0 + third_party_settings: { } + weight: 110 + region: content + field_image: + type: image + label: hidden + settings: + image_link: '' + image_style: wide + image_loading: + attribute: eager + third_party_settings: { } + weight: -1 + region: content + field_tags: + type: entity_reference_label + label: above + settings: + link: true + third_party_settings: { } + weight: 10 + region: content + field_video: + type: file_video + label: above + settings: + controls: true + autoplay: false + loop: false + multiple_file_display_type: tags + muted: true + width: 640 + height: 480 + third_party_settings: { } + weight: 111 + region: content + links: + settings: { } + third_party_settings: { } + weight: 100 + region: content +hidden: { } diff --git a/core/modules/file/tests/src/Functional/Formatter/FileVideoFormatterTest.php b/core/modules/file/tests/src/Functional/Formatter/FileVideoFormatterTest.php index 651fefdff9c9166cea7627ca06e1147d15be74a2..d25eedfc0a858686e905bea3563aafe59a1149fd 100644 --- a/core/modules/file/tests/src/Functional/Formatter/FileVideoFormatterTest.php +++ b/core/modules/file/tests/src/Functional/Formatter/FileVideoFormatterTest.php @@ -73,6 +73,7 @@ public function testAttributes(): void { 'autoplay' => TRUE, 'loop' => TRUE, 'muted' => TRUE, + 'playsinline' => TRUE, 'width' => 800, 'height' => 600, ] @@ -102,6 +103,7 @@ public function testAttributes(): void { $assert_session->elementExists('css', "video[autoplay='autoplay'] > source[src='$file_url'][type='video/mp4']"); $assert_session->elementExists('css', "video[loop='loop'] > source[src='$file_url'][type='video/mp4']"); $assert_session->elementExists('css', "video[muted='muted'] > source[src='$file_url'][type='video/mp4']"); + $assert_session->elementExists('css', "video[playsinline='playsinline'] > source[src='$file_url'][type='video/mp4']"); $assert_session->elementExists('css', "video[width='800'] > source[src='$file_url'][type='video/mp4']"); $assert_session->elementExists('css', "video[height='600'] > source[src='$file_url'][type='video/mp4']"); diff --git a/core/modules/file/tests/src/Functional/Formatter/FileVideoFormatterUpdateTest.php b/core/modules/file/tests/src/Functional/Formatter/FileVideoFormatterUpdateTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e5d5f31f14c6e12106213797d86477c0295dc031 --- /dev/null +++ b/core/modules/file/tests/src/Functional/Formatter/FileVideoFormatterUpdateTest.php @@ -0,0 +1,51 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\file\Functional\Formatter; + +use Drupal\FunctionalTests\Update\UpdatePathTestBase; + +/** + * Tests the upgrade path for video formatters. + * + * @see file_post_update_add_playsinline() + * + * @group Update + * @group legacy + */ +class FileVideoFormatterUpdateTest extends UpdatePathTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ['file', 'media']; + + /** + * {@inheritdoc} + */ + protected function setDatabaseDumpFiles(): void { + $this->databaseDumpFiles = [ + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-10.3.0.bare.standard.php.gz', + __DIR__ . '/../../../fixtures/update/file_post_update_playsinline-3046152.php', + ]; + } + + /** + * @covers \file_post_update_add_playsinline + */ + public function testPlaysInlineUpdate(): void { + $display = $this->config('core.entity_view_display.node.article.default'); + + $settings = $display->get('content.field_video.settings'); + $this->assertArrayNotHasKey('playsinline', $settings); + + $this->runUpdates(); + + $display = $this->config('core.entity_view_display.node.article.default'); + $settings = $display->get('content.field_video.settings'); + + $this->assertFalse($settings['playsinline']); + } + +} diff --git a/core/profiles/demo_umami/config/install/core.entity_view_display.media.video.default.yml b/core/profiles/demo_umami/config/install/core.entity_view_display.media.video.default.yml index b8ea26fd67d14ddb2d3169a422fe08ab0518376b..eb4585ef075391afdcc43c7c8483b0c5a9527d41 100644 --- a/core/profiles/demo_umami/config/install/core.entity_view_display.media.video.default.yml +++ b/core/profiles/demo_umami/config/install/core.entity_view_display.media.video.default.yml @@ -21,6 +21,7 @@ content: loop: false multiple_file_display_type: tags muted: false + playsinline: false width: 640 height: 480 third_party_settings: { } diff --git a/core/profiles/standard/config/optional/core.entity_view_display.media.video.default.yml b/core/profiles/standard/config/optional/core.entity_view_display.media.video.default.yml index 5ef0df791b61088cf011ab4d91905bbb46ca5128..b90e5998e88f931881d185e4ac1ac2b960b5c3a5 100644 --- a/core/profiles/standard/config/optional/core.entity_view_display.media.video.default.yml +++ b/core/profiles/standard/config/optional/core.entity_view_display.media.video.default.yml @@ -21,6 +21,7 @@ content: loop: false multiple_file_display_type: tags muted: false + playsinline: false width: 640 height: 480 third_party_settings: { } diff --git a/core/recipes/local_video_media_type/config/core.entity_view_display.media.video.default.yml b/core/recipes/local_video_media_type/config/core.entity_view_display.media.video.default.yml index 5ef0df791b61088cf011ab4d91905bbb46ca5128..b90e5998e88f931881d185e4ac1ac2b960b5c3a5 100644 --- a/core/recipes/local_video_media_type/config/core.entity_view_display.media.video.default.yml +++ b/core/recipes/local_video_media_type/config/core.entity_view_display.media.video.default.yml @@ -21,6 +21,7 @@ content: loop: false multiple_file_display_type: tags muted: false + playsinline: false width: 640 height: 480 third_party_settings: { }