From 3819ba9a26b6b2ee4eb73caac41907e3d88d2788 Mon Sep 17 00:00:00 2001 From: "H. C. Kruse" Date: Mon, 30 Oct 2023 10:06:33 +0100 Subject: [PATCH] feat: Add direct link to embeds Only if consent is active Implements #71 --- includes/EmbedService/EmbedHtmlFormatter.php | 9 ++++++++- resources/ext.embedVideo.consent.less | 10 +++++++++- resources/modules/iframe.js | 20 +++++++++++++++---- .../EmbedService/EmbedHtmlFormatterTest.php | 15 +++++++++++++- tests/phpunit/EmbedVideoTest.php | 2 +- 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/includes/EmbedService/EmbedHtmlFormatter.php b/includes/EmbedService/EmbedHtmlFormatter.php index 1ba7b03..764a4f7 100644 --- a/includes/EmbedService/EmbedHtmlFormatter.php +++ b/includes/EmbedService/EmbedHtmlFormatter.php @@ -6,6 +6,7 @@ use ConfigException; use Exception; +use Html; use JsonException; use MediaWiki\Extension\EmbedVideo\EmbedVideo; use MediaWiki\Extension\EmbedVideo\OEmbed; @@ -203,7 +204,13 @@ public static function makeTitleHtml( AbstractEmbedService $service ): string { return ''; } - return sprintf( '
%s
', $service->getTitle() ); + $link = Html::element( 'a', [ + 'target' => '_blank', + 'href' => $service->getUrl(), + 'rel' => 'noopener noreferrer nofollow' + ], $service->getTitle() ); + + return sprintf( '
%s
', $link ); } /** diff --git a/resources/ext.embedVideo.consent.less b/resources/ext.embedVideo.consent.less index a095be1..740bf35 100644 --- a/resources/ext.embedVideo.consent.less +++ b/resources/ext.embedVideo.consent.less @@ -63,6 +63,14 @@ text-overflow: ellipsis; overflow: hidden; white-space: nowrap; + + a { + color: #eaecf0; + + &:hover { + color: #fff; + } + } } &__fakeButton { @@ -108,7 +116,7 @@ .embedvideo-loader { &__title, &__footer { - opacity: 0; + //opacity: 0; } &__fakeButton { diff --git a/resources/modules/iframe.js b/resources/modules/iframe.js index 8717854..84cc6de 100644 --- a/resources/modules/iframe.js +++ b/resources/modules/iframe.js @@ -9,7 +9,7 @@ const fetchThumb = async (url, parent, container) => { // Title const overlay = parent.querySelector('.embedvideo-loader'); - overlay.querySelectorAll('.embedvideo-loader__title').forEach(title => { + overlay.querySelectorAll('.embedvideo-loader__title:not(.embedvideo-loader__title--manual)').forEach(title => { overlay.removeChild(title); }); @@ -73,13 +73,21 @@ const fetchThumb = async (url, parent, container) => { picture.append(image); parent.prepend(picture); - if (typeof json.title !== 'undefined' && json.title.length > 0) { + if (typeof json.title !== 'undefined' && json.title.length > 0 && parent.querySelector('.embedvideo-loader__title--manual') === null) { const overlay = parent.querySelector('.embedvideo-loader'), - title = document.createElement('div'); + title = document.createElement('div'), + link = document.createElement('a'); title.classList.add('embedvideo-loader__title'); - title.innerText = json.title; + + link.classList.add('embedvideo-loader__link'); + link.href = JSON.parse(container?.dataset?.iframeconfig ?? '{"src": "#"}').src; + link.target = '_blank'; + link.rel = 'noopener noreferrer nofollow'; + link.innerText = json.title; + + title.append(link); overlay.prepend(title); } @@ -145,6 +153,10 @@ const makeIframe = function(ev) { const togglePrivacyClickListener = function (event) { event.stopPropagation(); + if (event.target.classList.contains('embedvideo-loader__link')) { + return; + } + loader.classList.toggle('hidden'); privacyNotice.classList.toggle('hidden'); }; diff --git a/tests/phpunit/EmbedService/EmbedHtmlFormatterTest.php b/tests/phpunit/EmbedService/EmbedHtmlFormatterTest.php index 1b93eed..099a115 100644 --- a/tests/phpunit/EmbedService/EmbedHtmlFormatterTest.php +++ b/tests/phpunit/EmbedService/EmbedHtmlFormatterTest.php @@ -4,6 +4,7 @@ namespace MediaWiki\Extension\EmbedVideo\Tests\EmbedService; +use Html; use MediaWiki\Extension\EmbedVideo\EmbedService\EmbedHtmlFormatter; use MediaWiki\Extension\EmbedVideo\EmbedService\EmbedServiceFactory; use MediaWiki\Extension\EmbedVideo\EmbedService\LocalVideo; @@ -148,7 +149,19 @@ public function testMakeTitleHtml() { $output = EmbedHtmlFormatter::makeTitleHtml( $service ); - $this->assertEquals( '
Foo
', $output ); + $link = Html::element( 'a', [ + 'target' => '_blank', + 'href' => $service->getUrl(), + 'rel' => 'noopener noreferrer nofollow' + ], $service->getTitle() ); + + $this->assertEquals( + sprintf( + '
%s
', + $link + ), + $output + ); } /** diff --git a/tests/phpunit/EmbedVideoTest.php b/tests/phpunit/EmbedVideoTest.php index fc47ad2..233b2b0 100644 --- a/tests/phpunit/EmbedVideoTest.php +++ b/tests/phpunit/EmbedVideoTest.php @@ -409,7 +409,7 @@ public function testParseArgsExample6() { $this->assertCount( 3, $output ); $this->assertStringContainsString( '"width":320,"height":320', $output[0] ); $this->assertStringContainsString( - '
Title of the Embed
', + '