diff --git a/tests/ImageProxyTest.php b/tests/ImageProxyTest.php index 78d099e5..8049d7db 100644 --- a/tests/ImageProxyTest.php +++ b/tests/ImageProxyTest.php @@ -66,6 +66,7 @@ public function run(): void { $this->testInvalidUtf8(); $this->testHtmlDocumentsAndTagSoup(); $this->testImageAttributes(); + $this->testVideoPosters(); $this->testUriSchemes(); } catch (FreshRSS_Context_Exception $e) { throw new RuntimeException('ImageProxy configuration failed', 0, $e); @@ -163,6 +164,28 @@ private function testImageAttributes(): void { $this->assertSame(false, $images[2]->hasAttribute('src'), 'Images without src must remain without src'); } + /** @throws FreshRSS_Context_Exception */ + private function testVideoPosters(): void { + $input = '' + . ''; + $output = ImageProxyExtension::swapUris($input); + $videos = $this->elements($output, 'video'); + + $this->assertSame(2, count($videos), 'All video elements must remain present'); + $this->assertSame( + self::PROXY_URL . 'http://images.example/poster.jpg', + $videos[0]->getAttribute('poster'), + 'Video posters must be proxied', + ); + $this->assertSame( + 'http://images.example/poster.jpg', + $videos[0]->getAttribute('data-xextension-imageproxy-original-poster'), + 'Original poster must be retained', + ); + $this->assertSame('https://videos.example/one.mp4', $videos[0]->getAttribute('src'), 'Video sources must not be proxied'); + $this->assertSame(false, $videos[1]->hasAttribute('poster'), 'Videos without poster must remain without poster'); + } + /** @throws FreshRSS_Context_Exception */ private function testUriSchemes(): void { $this->assertSame( @@ -197,14 +220,19 @@ private function textContent(string $html): string { /** @return list */ private function images(string $html): array { + return $this->elements($html, 'img'); + } + + /** @return list */ + private function elements(string $html, string $tagName): array { $doc = $this->parseFragment($html); - $images = []; - foreach ($doc->getElementsByTagName('img') as $image) { - if ($image instanceof DOMElement) { - $images[] = $image; + $elements = []; + foreach ($doc->getElementsByTagName($tagName) as $element) { + if ($element instanceof DOMElement) { + $elements[] = $element; } } - return $images; + return $elements; } private function parseFragment(string $html): DOMDocument { diff --git a/xExtension-ImageProxy/README.md b/xExtension-ImageProxy/README.md index 78ff7888..e58edc29 100644 --- a/xExtension-ImageProxy/README.md +++ b/xExtension-ImageProxy/README.md @@ -6,6 +6,7 @@ To use it, upload this entire directory to the FreshRSS `./extensions` directory ## Changelog +* 1.0.3 Proxy the poster images of videos * 1.0.1 Replace deprecated HTML entity conversion on PHP 8.2+ * 1.0 Breaking changes due to significant code upgrade: settings must be saved again * 0.7.3 Turkish language support added diff --git a/xExtension-ImageProxy/extension.php b/xExtension-ImageProxy/extension.php index dd233dd5..ebd056eb 100644 --- a/xExtension-ImageProxy/extension.php +++ b/xExtension-ImageProxy/extension.php @@ -157,6 +157,17 @@ public static function swapUris(string $content): string { } } + // Video posters are images too; keep the original URL for the same reason as above + $videos = $doc->getElementsByTagName('video'); + foreach ($videos as $video) { + if (!($video instanceof DOMElement) || !$video->hasAttribute('poster')) { + continue; + } + $poster = $video->getAttribute('poster'); + $video->setAttribute('data-xextension-imageproxy-original-poster', $poster); + $video->setAttribute('poster', self::getProxyImageUri($poster)); + } + $body = $doc->getElementsByTagName('body')->item(0); $output = $doc->saveHTML($body); diff --git a/xExtension-ImageProxy/metadata.json b/xExtension-ImageProxy/metadata.json index 979786c0..9f9141c5 100644 --- a/xExtension-ImageProxy/metadata.json +++ b/xExtension-ImageProxy/metadata.json @@ -2,7 +2,7 @@ "name": "Image Proxy", "author": "Frans de Jonge", "description": "No insecure content warnings or disappearing images.", - "version": "1.0.2", + "version": "1.0.3", "entrypoint": "ImageProxy", "type": "user" }