.../Resource/Rendering/AudioTagRenderer.php | 42 ++++++++++++----------
.../Resource/Rendering/VideoTagRenderer.php | 42 ++++++++++++----------
.../core/Configuration/TCA/sys_file_reference.php | 42 ++++++++++++++++++++--
.../Resource/Rendering/AudioTagRendererTest.php | 36 ++++++++++++++++++-
.../Resource/Rendering/VideoTagRendererTest.php | 36 ++++++++++++++++++-
.../Unit/Resource/Rendering/VimeoRendererTest.php | 2 +-
.../Resource/Rendering/YouTubeRendererTest.php | 2 +-
typo3/sysext/core/ext_tables.sql | 4 +++
typo3/sysext/lang/locallang_tca.xlf | 21 +++++++++++
9 files changed, 183 insertions(+), 44 deletions(-)
diff --git a/typo3/sysext/core/Classes/Resource/Rendering/AudioTagRenderer.php b/typo3/sysext/core/Classes/Resource/Rendering/AudioTagRenderer.php
index e1a0986..46d469b 100644
--- a/typo3/sysext/core/Classes/Resource/Rendering/AudioTagRenderer.php
+++ b/typo3/sysext/core/Classes/Resource/Rendering/AudioTagRenderer.php
@@ -30,6 +30,13 @@ class AudioTagRenderer implements FileRendererInterface
protected $possibleMimeTypes = ['audio/mpeg', 'audio/wav', 'audio/ogg'];
/**
+ * Attributes for HTML Audio Tag
+ *
+ * @var array
+ */
+ protected $possibleAudioAttributes = ['autoplay', 'muted', 'loop', 'controls', 'preload'];
+
+ /**
* Returns the priority of the renderer
* This way it is possible to define/overrule a renderer
* for a specific file type/context.
@@ -66,37 +73,34 @@ class AudioTagRenderer implements FileRendererInterface
*/
public function render(FileInterface $file, $width, $height, array $options = [], $usedPathsRelativeToCurrentScript = false)
{
-
- // If autoplay isn't set manually check if $file is a FileReference take autoplay from there
- if (!isset($options['autoplay']) && $file instanceof FileReference) {
- $autoplay = $file->getProperty('autoplay');
- if ($autoplay !== null) {
- $options['autoplay'] = $autoplay;
+ if ($file instanceof FileReference) {
+ foreach ($this->possibleAudioAttributes as $audioTagAttribute) {
+ // If video tag attribute isn't set manually check if $file is a FileReference take custom attribute from there
+ if (!isset($options[$audioTagAttribute])) {
+ $fileAttribute = $file->getProperty($audioTagAttribute);
+ if ($fileAttribute !== null) {
+ $options[$audioTagAttribute] = $fileAttribute;
+ }
+ }
}
}
$additionalAttributes = [];
- if (!isset($options['controls']) || !empty($options['controls'])) {
- $additionalAttributes[] = 'controls';
- }
- if (!empty($options['autoplay'])) {
- $additionalAttributes[] = 'autoplay';
- }
- if (!empty($options['muted'])) {
- $additionalAttributes[] = 'muted';
- }
- if (!empty($options['loop'])) {
- $additionalAttributes[] = 'loop';
+ // check additional attributes from template
+ foreach ($this->possibleAudioAttributes as $key) {
+ if (!isset($options[$key]) || !empty($options[$key])) {
+ $additionalAttributes[$key] = $key;
+ }
}
foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick', 'preload'] as $key) {
if (!empty($options[$key])) {
- $additionalAttributes[] = $key . '="' . htmlspecialchars($options[$key]) . '"';
+ $additionalAttributes[$key] = $key . '="' . htmlspecialchars($options[$key]) . '"';
}
}
return sprintf(
'',
- empty($additionalAttributes) ? '' : ' ' . implode(' ', $additionalAttributes),
+ empty($additionalAttributes) ? '' : ' ' . implode(' ', array_unique($additionalAttributes)),
htmlspecialchars($file->getPublicUrl($usedPathsRelativeToCurrentScript)),
$file->getMimeType()
);
diff --git a/typo3/sysext/core/Classes/Resource/Rendering/VideoTagRenderer.php b/typo3/sysext/core/Classes/Resource/Rendering/VideoTagRenderer.php
index 171ca50..7e5a776 100644
--- a/typo3/sysext/core/Classes/Resource/Rendering/VideoTagRenderer.php
+++ b/typo3/sysext/core/Classes/Resource/Rendering/VideoTagRenderer.php
@@ -30,6 +30,13 @@ class VideoTagRenderer implements FileRendererInterface
protected $possibleMimeTypes = ['video/mp4', 'video/webm', 'video/ogg', 'application/ogg'];
/**
+ * Attributes for HTML Video Tag
+ *
+ * @var array
+ */
+ protected $possibleVideoAttributes = ['autoplay', 'muted', 'preload', 'loop', 'controls'];
+
+ /**
* Returns the priority of the renderer
* This way it is possible to define/overrule a renderer
* for a specific file type/context.
@@ -66,35 +73,32 @@ class VideoTagRenderer implements FileRendererInterface
*/
public function render(FileInterface $file, $width, $height, array $options = [], $usedPathsRelativeToCurrentScript = false)
{
-
- // If autoplay isn't set manually check if $file is a FileReference take autoplay from there
- if (!isset($options['autoplay']) && $file instanceof FileReference) {
- $autoplay = $file->getProperty('autoplay');
- if ($autoplay !== null) {
- $options['autoplay'] = $autoplay;
+ if ($file instanceof FileReference) {
+ foreach ($this->possibleVideoAttributes as $videoTagAttribute) {
+ // If video tag attribute isn't set manually check if $file is a FileReference take custom attribute from there
+ if (!isset($options[$videoTagAttribute])) {
+ $fileAttribute = $file->getProperty($videoTagAttribute);
+ if ($fileAttribute !== null) {
+ $options[$videoTagAttribute] = $fileAttribute;
+ }
+ }
}
}
$attributes = [];
+ // check additional attributes from template
if ((int)$width > 0) {
$attributes[] = 'width="' . (int)$width . '"';
}
if ((int)$height > 0) {
$attributes[] = 'height="' . (int)$height . '"';
}
- if (!isset($options['controls']) || !empty($options['controls'])) {
- $attributes[] = 'controls';
- }
- if (!empty($options['autoplay'])) {
- $attributes[] = 'autoplay';
- }
- if (!empty($options['muted'])) {
- $attributes[] = 'muted';
- }
- if (!empty($options['loop'])) {
- $attributes[] = 'loop';
+ foreach ($this->possibleVideoAttributes as $key) {
+ if (!isset($options[$key]) || !empty($options[$key])) {
+ $attributes[$key] = $key;
+ }
}
- foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick'] as $key) {
+ foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick', 'preload'] as $key) {
if (!empty($options[$key])) {
$attributes[] = $key . '="' . htmlspecialchars($options[$key]) . '"';
}
@@ -102,7 +106,7 @@ class VideoTagRenderer implements FileRendererInterface
return sprintf(
'',
- empty($attributes) ? '' : ' ' . implode(' ', $attributes),
+ empty($attributes) ? '' : ' ' . implode(' ', array_unique($attributes)),
htmlspecialchars($file->getPublicUrl($usedPathsRelativeToCurrentScript)),
$file->getMimeType()
);
diff --git a/typo3/sysext/core/Configuration/TCA/sys_file_reference.php b/typo3/sysext/core/Configuration/TCA/sys_file_reference.php
index 5e1c355..de2ff9c 100644
--- a/typo3/sysext/core/Configuration/TCA/sys_file_reference.php
+++ b/typo3/sysext/core/Configuration/TCA/sys_file_reference.php
@@ -224,6 +224,44 @@ return [
'default' => 0
]
],
+ 'loop' => [
+ 'exclude' => true,
+ 'label' => 'LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.loop',
+ 'config' => [
+ 'type' => 'check',
+ 'default' => 0
+ ]
+ ],
+ 'muted' => [
+ 'exclude' => true,
+ 'label' => 'LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.muted',
+ 'config' => [
+ 'type' => 'check',
+ 'default' => 0
+ ]
+ ],
+ 'preload' => [
+ 'exclude' => true,
+ 'label' => 'LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.preload',
+ 'config' => [
+ 'type' => 'select',
+ 'renderType' => 'selectSingle',
+ 'items' => [
+ ['LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.preload.auto', 'auto'],
+ ['LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.preload.none', 'none'],
+ ['LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.preload.metadata', 'metadata']
+ ],
+ 'default' => 'auto'
+ ]
+ ],
+ 'controls' => [
+ 'exclude' => true,
+ 'label' => 'LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.controls',
+ 'config' => [
+ 'type' => 'check',
+ 'default' => 0
+ ]
+ ],
],
'types' => [
// Note that at the moment we define the same fields for every media type.
@@ -274,13 +312,13 @@ return [
// Used for everything that is a video
'videoOverlayPalette' => [
'showitem' => '
- title,description,--linebreak--,autoplay
+ title,description,--linebreak--,autoplay,controls,loop,muted,--linebreak--,preload
',
],
// Used for everything that is a audio file
'audioOverlayPalette' => [
'showitem' => '
- title,description,--linebreak--,autoplay
+ title,description,--linebreak--,autoplay,controls,loop,muted,--linebreak--,preload
',
],
// File palette, hidden but needs to be included all the time
diff --git a/typo3/sysext/core/Tests/Unit/Resource/Rendering/AudioTagRendererTest.php b/typo3/sysext/core/Tests/Unit/Resource/Rendering/AudioTagRendererTest.php
index f2d4c54..7f83ff2 100644
--- a/typo3/sysext/core/Tests/Unit/Resource/Rendering/AudioTagRendererTest.php
+++ b/typo3/sysext/core/Tests/Unit/Resource/Rendering/AudioTagRendererTest.php
@@ -115,7 +115,7 @@ class AudioTagRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
/**
* @test
*/
- public function renderOutputWithAutoplayAndWithoutControllsIsCorrect()
+ public function renderOutputWithAutoplayAndWithoutControlsIsCorrect()
{
$audioTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\AudioTagRenderer();
@@ -128,4 +128,38 @@ class AudioTagRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
$audioTagRenderer->render($fileResourceMock, '300m', '200', ['controls' => 0, 'autoplay' => 1])
);
}
+
+ /**
+ * @test
+ */
+ public function renderOutputWithMutedIsCorrect()
+ {
+ $audioTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\AudioTagRenderer();
+
+ $fileResourceMock = $this->createMock(\TYPO3\CMS\Core\Resource\File::class);
+ $fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('audio/mpeg'));
+ $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myAudioFile'));
+
+ $this->assertSame(
+ '',
+ $audioTagRenderer->render($fileResourceMock, '300m', '200', ['muted' => 1])
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function renderOutputWithPreloadIsCorrect()
+ {
+ $audioTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\AudioTagRenderer();
+
+ $fileResourceMock = $this->createMock(\TYPO3\CMS\Core\Resource\File::class);
+ $fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('audio/mpeg'));
+ $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myAudioFile'));
+
+ $this->assertSame(
+ '',
+ $audioTagRenderer->render($fileResourceMock, '300m', '200', ['preload' => 'auto'])
+ );
+ }
}
diff --git a/typo3/sysext/core/Tests/Unit/Resource/Rendering/VideoTagRendererTest.php b/typo3/sysext/core/Tests/Unit/Resource/Rendering/VideoTagRendererTest.php
index 6f19940..84d0467 100644
--- a/typo3/sysext/core/Tests/Unit/Resource/Rendering/VideoTagRendererTest.php
+++ b/typo3/sysext/core/Tests/Unit/Resource/Rendering/VideoTagRendererTest.php
@@ -118,7 +118,7 @@ class VideoTagRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
/**
* @test
*/
- public function renderOutputWithAutoplayAndWithoutControllsIsCorrect()
+ public function renderOutputWithAutoplayAndWithoutControlsIsCorrect()
{
$VideoTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\VideoTagRenderer();
@@ -131,4 +131,38 @@ class VideoTagRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
$VideoTagRenderer->render($fileResourceMock, '300m', '200', ['controls' => 0, 'autoplay' => 1])
);
}
+
+ /**
+ * @test
+ */
+ public function renderOutputWithMutedIsCorrect()
+ {
+ $VideoTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\VideoTagRenderer();
+
+ $fileResourceMock = $this->createMock(\TYPO3\CMS\Core\Resource\File::class);
+ $fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('video/mp4'));
+ $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myVideoFile'));
+
+ $this->assertSame(
+ '',
+ $VideoTagRenderer->render($fileResourceMock, '300m', '200', ['muted' => 1])
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function renderOutputWithPreloadIsCorrect()
+ {
+ $VideoTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\VideoTagRenderer();
+
+ $fileResourceMock = $this->createMock(\TYPO3\CMS\Core\Resource\File::class);
+ $fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('video/mp4'));
+ $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myVideoFile'));
+
+ $this->assertSame(
+ '',
+ $VideoTagRenderer->render($fileResourceMock, '300m', '200', ['preload' => 'auto'])
+ );
+ }
}
diff --git a/typo3/sysext/core/Tests/Unit/Resource/Rendering/VimeoRendererTest.php b/typo3/sysext/core/Tests/Unit/Resource/Rendering/VimeoRendererTest.php
index 7834da3..7b39813 100644
--- a/typo3/sysext/core/Tests/Unit/Resource/Rendering/VimeoRendererTest.php
+++ b/typo3/sysext/core/Tests/Unit/Resource/Rendering/VimeoRendererTest.php
@@ -146,7 +146,7 @@ class VimeoRendererTest extends UnitTestCase
/**
* @test
*/
- public function renderOutputWithAutoplayAndWithoutControllsIsCorrect()
+ public function renderOutputWithAutoplayAndWithoutControlsIsCorrect()
{
/** @var File|\PHPUnit_Framework_MockObject_MockObject $fileResourceMock */
$fileResourceMock = $this->createMock(File::class);
diff --git a/typo3/sysext/core/Tests/Unit/Resource/Rendering/YouTubeRendererTest.php b/typo3/sysext/core/Tests/Unit/Resource/Rendering/YouTubeRendererTest.php
index 0e3eeb5..389bc7c 100644
--- a/typo3/sysext/core/Tests/Unit/Resource/Rendering/YouTubeRendererTest.php
+++ b/typo3/sysext/core/Tests/Unit/Resource/Rendering/YouTubeRendererTest.php
@@ -149,7 +149,7 @@ class YouTubeRendererTest extends UnitTestCase
/**
* @test
*/
- public function renderOutputWithAutoplayAndWithoutControllsIsCorrect()
+ public function renderOutputWithAutoplayAndWithoutControlsIsCorrect()
{
/** @var File|\PHPUnit_Framework_MockObject_MockObject $fileResourceMock */
$fileResourceMock = $this->createMock(File::class);
diff --git a/typo3/sysext/core/ext_tables.sql b/typo3/sysext/core/ext_tables.sql
index 6f90ed9..c859f78 100644
--- a/typo3/sysext/core/ext_tables.sql
+++ b/typo3/sysext/core/ext_tables.sql
@@ -416,6 +416,10 @@ CREATE TABLE sys_file_reference (
link varchar(1024) DEFAULT '' NOT NULL,
crop varchar(4000) DEFAULT '' NOT NULL,
autoplay tinyint(4) DEFAULT '0' NOT NULL,
+ preload varchar(8) DEFAULT '' NOT NULL,
+ controls tinyint(4) DEFAULT '0' NOT NULL,
+ muted tinyint(4) DEFAULT '0' NOT NULL,
+ loop tinyint(4) DEFAULT '0' NOT NULL,
PRIMARY KEY (uid),
KEY parent (pid,deleted),
diff --git a/typo3/sysext/lang/locallang_tca.xlf b/typo3/sysext/lang/locallang_tca.xlf
index c5bdc22..c141a7b 100644
--- a/typo3/sysext/lang/locallang_tca.xlf
+++ b/typo3/sysext/lang/locallang_tca.xlf
@@ -561,6 +561,27 @@
Autoplay
+
+ Controls
+
+
+ Muted
+
+
+ Loop
+
+
+ Preload
+
+
+ Auto
+
+
+ None
+
+
+ Metadata
+
File collection