From 61eaad5dda490934907208d4b7bd72ce0646ba7f Mon Sep 17 00:00:00 2001
From: Andreas Fernandez <a.fernandez@scripting-base.de>
Date: Thu, 21 Dec 2017 14:18:32 +0100
Subject: [PATCH] [BUGFIX] Add `controlsList` as known additional attribute

The HTML5 attribute `controlsList` is used in at least Google Chrome
to limit the control buttons. The AudioTagRenderer and VideoTagRenderer
classes are now aware of that attribute.

Resolves: #81222
Releases: master, 8.7, 7.6
Change-Id: I9a577ae077e7e7b55b9fed7852a5a61a5fd4061a
Reviewed-on: https://review.typo3.org/55187
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Jigal van Hemert <jigal.van.hemert@typo3.org>
Tested-by: Jigal van Hemert <jigal.van.hemert@typo3.org>
---
 .../Resource/Rendering/AudioTagRenderer.php   |  2 +-
 .../Resource/Rendering/VideoTagRenderer.php   |  2 +-
 .../Rendering/AudioTagRendererTest.php        | 89 ++++++++-----------
 .../Rendering/VideoTagRendererTest.php        | 89 ++++++++-----------
 4 files changed, 78 insertions(+), 104 deletions(-)

diff --git a/typo3/sysext/core/Classes/Resource/Rendering/AudioTagRenderer.php b/typo3/sysext/core/Classes/Resource/Rendering/AudioTagRenderer.php
index e1a098679f56..0d5ba40a6f0f 100644
--- a/typo3/sysext/core/Classes/Resource/Rendering/AudioTagRenderer.php
+++ b/typo3/sysext/core/Classes/Resource/Rendering/AudioTagRenderer.php
@@ -88,7 +88,7 @@ class AudioTagRenderer implements FileRendererInterface
         if (!empty($options['loop'])) {
             $additionalAttributes[] = 'loop';
         }
-        foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick', 'preload'] as $key) {
+        foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick', 'preload', 'controlsList'] as $key) {
             if (!empty($options[$key])) {
                 $additionalAttributes[] = $key . '="' . htmlspecialchars($options[$key]) . '"';
             }
diff --git a/typo3/sysext/core/Classes/Resource/Rendering/VideoTagRenderer.php b/typo3/sysext/core/Classes/Resource/Rendering/VideoTagRenderer.php
index 171ca50a5492..6247282623e6 100644
--- a/typo3/sysext/core/Classes/Resource/Rendering/VideoTagRenderer.php
+++ b/typo3/sysext/core/Classes/Resource/Rendering/VideoTagRenderer.php
@@ -94,7 +94,7 @@ class VideoTagRenderer implements FileRendererInterface
         if (!empty($options['loop'])) {
             $attributes[] = 'loop';
         }
-        foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick'] as $key) {
+        foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick', 'controlsList'] as $key) {
             if (!empty($options[$key])) {
                 $attributes[] = $key . '="' . htmlspecialchars($options[$key]) . '"';
             }
diff --git a/typo3/sysext/core/Tests/Unit/Resource/Rendering/AudioTagRendererTest.php b/typo3/sysext/core/Tests/Unit/Resource/Rendering/AudioTagRendererTest.php
index bc38bc2e9f54..329b98cc1e27 100644
--- a/typo3/sysext/core/Tests/Unit/Resource/Rendering/AudioTagRendererTest.php
+++ b/typo3/sysext/core/Tests/Unit/Resource/Rendering/AudioTagRendererTest.php
@@ -62,70 +62,57 @@ class AudioTagRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
     }
 
     /**
-     * @test
+     * Array of configurations
      */
-    public function renderOutputIsCorrect()
+    public function renderArgumentsDataProvider()
     {
-        $audioTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\AudioTagRenderer();
-
-        $fileResourceMock = $this->getMock(\TYPO3\CMS\Core\Resource\File::class, [], [], '', false);
-        $fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('audio/mpeg'));
-        $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myAudioFile?foo=bar&baz=true'));
-
-        $this->assertSame(
-            '<audio controls><source src="//:path/myAudioFile?foo=bar&amp;baz=true" type="audio/mpeg"></audio>',
-            $audioTagRenderer->render($fileResourceMock, '300m', '200')
-        );
+        return [
+            [
+                '//:path/myAudioFile?foo=bar&baz=true',
+                [],
+                '<audio controls><source src="//:path/myAudioFile?foo=bar&amp;baz=true" type="audio/mpeg"></audio>',
+            ],
+            [
+                '//:path/myAudioFile',
+                ['loop' => 1],
+                '<audio controls loop><source src="//:path/myAudioFile" type="audio/mpeg"></audio>',
+            ],
+            [
+                '//:path/myAudioFile',
+                ['autoplay' => 1],
+                '<audio controls autoplay><source src="//:path/myAudioFile" type="audio/mpeg"></audio>',
+            ],
+            [
+                '//:path/myAudioFile',
+                ['controls' => 0, 'autoplay' => 1],
+                '<audio autoplay><source src="//:path/myAudioFile" type="audio/mpeg"></audio>',
+            ],
+            [
+                '//:path/myAudioFile',
+                ['controls' => 1, 'controlsList' => 'nodownload'],
+                '<audio controls controlsList="nodownload"><source src="//:path/myAudioFile" type="audio/mpeg"></audio>',
+            ]
+        ];
     }
 
     /**
      * @test
+     * @dataProvider renderArgumentsDataProvider
+     * @param string $url
+     * @param array $arguments
+     * @param string $expected
      */
-    public function renderOutputWithLoopIsCorrect()
+    public function renderOutputIsCorrect($url, $arguments, $expected)
     {
         $audioTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\AudioTagRenderer();
 
-        $fileResourceMock = $this->getMock(\TYPO3\CMS\Core\Resource\File::class, [], [], '', false);
-        $fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('audio/mpeg'));
-        $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myAudioFile'));
-
-        $this->assertSame(
-            '<audio controls loop><source src="//:path/myAudioFile" type="audio/mpeg"></audio>',
-            $audioTagRenderer->render($fileResourceMock, '300m', '200', ['loop' => 1])
-        );
-    }
-
-    /**
-     * @test
-     */
-    public function renderOutputWithAutoplayIsCorrect()
-    {
-        $audioTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\AudioTagRenderer();
-
-        $fileResourceMock = $this->getMock(\TYPO3\CMS\Core\Resource\File::class, [], [], '', false);
-        $fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('audio/mpeg'));
-        $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myAudioFile'));
-
-        $this->assertSame(
-            '<audio controls autoplay><source src="//:path/myAudioFile" type="audio/mpeg"></audio>',
-            $audioTagRenderer->render($fileResourceMock, '300m', '200', ['autoplay' => 1])
-        );
-    }
-
-    /**
-     * @test
-     */
-    public function renderOutputWithAutoplayAndWithoutControllsIsCorrect()
-    {
-        $audioTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\AudioTagRenderer();
-
-        $fileResourceMock = $this->getMock(\TYPO3\CMS\Core\Resource\File::class, [], [], '', false);
+        $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'));
+        $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue($url));
 
         $this->assertSame(
-            '<audio autoplay><source src="//:path/myAudioFile" type="audio/mpeg"></audio>',
-            $audioTagRenderer->render($fileResourceMock, '300m', '200', ['controls' => 0, 'autoplay' => 1])
+            $expected,
+            $audioTagRenderer->render($fileResourceMock, '300m', '200', $arguments)
         );
     }
 }
diff --git a/typo3/sysext/core/Tests/Unit/Resource/Rendering/VideoTagRendererTest.php b/typo3/sysext/core/Tests/Unit/Resource/Rendering/VideoTagRendererTest.php
index ac4604112657..e934de938cd3 100644
--- a/typo3/sysext/core/Tests/Unit/Resource/Rendering/VideoTagRendererTest.php
+++ b/typo3/sysext/core/Tests/Unit/Resource/Rendering/VideoTagRendererTest.php
@@ -65,70 +65,57 @@ class VideoTagRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
     }
 
     /**
-     * @test
+     * Array of configurations
      */
-    public function renderOutputIsCorrect()
+    public function renderArgumentsDataProvider()
     {
-        $VideoTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\VideoTagRenderer();
-
-        $fileResourceMock = $this->getMock(\TYPO3\CMS\Core\Resource\File::class, [], [], '', false);
-        $fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('video/mp4'));
-        $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myVideoFile?foo=bar&baz=true'));
-
-        $this->assertSame(
-            '<video width="300" height="200" controls><source src="//:path/myVideoFile?foo=bar&amp;baz=true" type="video/mp4"></video>',
-            $VideoTagRenderer->render($fileResourceMock, '300m', '200')
-        );
+        return [
+            [
+                '//:path/myVideoFile?foo=bar&baz=true',
+                [],
+                '<video width="300" height="200" controls><source src="//:path/myVideoFile?foo=bar&amp;baz=true" type="video/mp4"></video>',
+            ],
+            [
+                '//:path/myVideoFile',
+                ['loop' => 1],
+                '<video width="300" height="200" controls loop><source src="//:path/myVideoFile" type="video/mp4"></video>',
+            ],
+            [
+                '//:path/myVideoFile',
+                ['autoplay' => 1],
+                '<video width="300" height="200" controls autoplay><source src="//:path/myVideoFile" type="video/mp4"></video>',
+            ],
+            [
+                '//:path/myVideoFile',
+                ['controls' => 0, 'autoplay' => 1],
+                '<video width="300" height="200" autoplay><source src="//:path/myVideoFile" type="video/mp4"></video>',
+            ],
+            [
+                '//:path/myVideoFile',
+                ['controls' => 1, 'controlsList' => 'nodownload'],
+                '<video width="300" height="200" controls controlsList="nodownload"><source src="//:path/myVideoFile" type="video/mp4"></video>',
+            ]
+        ];
     }
 
     /**
      * @test
+     * @dataProvider renderArgumentsDataProvider
+     * @param string $url
+     * @param array $arguments
+     * @param string $expected
      */
-    public function renderOutputWithLoopIsCorrect()
+    public function renderOutputIsCorrect($url, $arguments, $expected)
     {
         $VideoTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\VideoTagRenderer();
 
-        $fileResourceMock = $this->getMock(\TYPO3\CMS\Core\Resource\File::class, [], [], '', false);
-        $fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('video/mp4'));
-        $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myVideoFile'));
-
-        $this->assertSame(
-            '<video width="300" height="200" controls loop><source src="//:path/myVideoFile" type="video/mp4"></video>',
-            $VideoTagRenderer->render($fileResourceMock, '300m', '200', ['loop' => 1])
-        );
-    }
-
-    /**
-     * @test
-     */
-    public function renderOutputWithAutoplayIsCorrect()
-    {
-        $VideoTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\VideoTagRenderer();
-
-        $fileResourceMock = $this->getMock(\TYPO3\CMS\Core\Resource\File::class, [], [], '', false);
-        $fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('video/mp4'));
-        $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myVideoFile'));
-
-        $this->assertSame(
-            '<video width="300" height="200" controls autoplay><source src="//:path/myVideoFile" type="video/mp4"></video>',
-            $VideoTagRenderer->render($fileResourceMock, '300m', '200', ['autoplay' => 1])
-        );
-    }
-
-    /**
-     * @test
-     */
-    public function renderOutputWithAutoplayAndWithoutControllsIsCorrect()
-    {
-        $VideoTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\VideoTagRenderer();
-
-        $fileResourceMock = $this->getMock(\TYPO3\CMS\Core\Resource\File::class, [], [], '', false);
+        $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'));
+        $fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue($url));
 
         $this->assertSame(
-            '<video width="300" height="200" autoplay><source src="//:path/myVideoFile" type="video/mp4"></video>',
-            $VideoTagRenderer->render($fileResourceMock, '300m', '200', ['controls' => 0, 'autoplay' => 1])
+            $expected,
+            $VideoTagRenderer->render($fileResourceMock, '300m', '200', $arguments)
         );
     }
 }
-- 
GitLab