Last active
March 16, 2025 21:20
-
-
Save ciencia/66a8d5eb6ad540f0bf94900358bc51c8 to your computer and use it in GitHub Desktop.
patch MediaWiki extension TimedMediaHandler autoplay videos REL1_43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/extension.json b/extension.json | |
index e5780d22..2d72f6b3 100644 | |
--- a/extension.json | |
+++ b/extension.json | |
@@ -127,10 +127,12 @@ | |
"FileDeleteComplete": "main", | |
"FileUndeleteComplete": "main", | |
"FileUpload": "main", | |
+ "GetPreferences": "main", | |
"ImageOpenShowImageInlineBefore": "main", | |
"ImagePageAfterImageLinks": "main", | |
"ImagePageFileHistoryLine": "main", | |
"LoadExtensionSchemaUpdates": "installer", | |
+ "MakeGlobalVariablesScript": "main", | |
"MediaWikiPerformAction": "iframe", | |
"RevisionFromEditComplete": "main", | |
"PageMoveComplete": [ | |
@@ -363,8 +365,16 @@ | |
"description": "Path of a soundfont to use for MIDI-converted audio", | |
"public": true, | |
"value": null | |
+ }, | |
+ "TmhEnableAutoPlayVideos": { | |
+ "description": "Allow videos to play automatically (but muted) using the autoplay attribute.", | |
+ "public": true, | |
+ "value": false | |
} | |
}, | |
+ "DefaultUserOptions": { | |
+ "timedmediahandler-autoplayvideos": "allow" | |
+ }, | |
"ForeignResourcesDir": "resources/lib", | |
"ResourceFileModulePaths": { | |
"localBasePath": "resources", | |
diff --git a/i18n/TimedMediaHandler.i18n.magic.php b/i18n/TimedMediaHandler.i18n.magic.php | |
index 737b4e06..4ba55f7a 100644 | |
--- a/i18n/TimedMediaHandler.i18n.magic.php | |
+++ b/i18n/TimedMediaHandler.i18n.magic.php | |
@@ -15,6 +15,7 @@ $magicWords['en'] = [ | |
'timedmedia_disablecontrols' => [ 0, 'disablecontrols=$1' ], | |
'timedmedia_loop' => [ 0, 'loop' ], | |
'timedmedia_muted' => [ 0, 'muted' ], | |
+ 'timedmedia_autoplay' => [ 0, 'autoplay' ], | |
]; | |
$magicWords['af'] = [ | |
diff --git a/i18n/en.json b/i18n/en.json | |
index 6504827b..a082bc22 100644 | |
--- a/i18n/en.json | |
+++ b/i18n/en.json | |
@@ -190,6 +190,9 @@ | |
"timedmedia-duration-hms": "{{PLURAL:$1|$1 hour|$1 hours}}, {{PLURAL:$2|$2 minute|$2 minutes}} and {{PLURAL:$3|$3 second|$3 seconds}}", | |
"timedmedia-duration-ms": "{{PLURAL:$1|$1 minute|$1 minutes}} and {{PLURAL:$2|$2 second|$2 seconds}}", | |
"timedmedia-duration-s": "{{PLURAL:$1|$1 second|$1 seconds}}", | |
+ "timedmedia-preference-autoplayvideos": "Behavior of videos marked to play automatically", | |
+ "timedmedia-preference-autoplayvideos-allow": "Allow videos marked as such to play automatically", | |
+ "timedmedia-preference-autoplayvideos-never": "Never play videos automatically", | |
"right-transcode-reset": "Reset failed or transcoded videos so they are inserted into the job queue again", | |
"right-transcode-status": "View [[Special:TimedMediaHandler|information about the current transcode activity]]", | |
"action-transcode-reset": "reset transcodes", | |
diff --git a/i18n/es.json b/i18n/es.json | |
index 93c6b91c..6b8fc26a 100644 | |
--- a/i18n/es.json | |
+++ b/i18n/es.json | |
@@ -139,6 +139,9 @@ | |
"timedmedia-duration-hms": "{{PLURAL:$1|$1 hora|$1 horas}}, {{PLURAL:$2|$2 minuto|$2 minutos}} y {{PLURAL:$3|$3 segundo|$3 segundos}}", | |
"timedmedia-duration-ms": "{{PLURAL:$1|$1 minuto|$1 minutos}} y {{PLURAL:$2|$2 segundo|$2 segundos}}", | |
"timedmedia-duration-s": "{{PLURAL:$1|$1 segundo|$1 segundos}}", | |
+ "timedmedia-preference-autoplayvideos": "Comportamiento de los vídeos marcados para su reproducción automática", | |
+ "timedmedia-preference-autoplayvideos-allow": "Permitir la reproducción automática de vídeos", | |
+ "timedmedia-preference-autoplayvideos-never": "Nunca permitir la reproducción automática de vídeos", | |
"right-transcode-reset": "Reiniciar los vídeos erróneos o transcodificados por lo que se vuelven a colocar en la cola de trabajo", | |
"right-transcode-status": "Ver [[Special:TimedMediaHandler|información sobre la actividad de transcodificación actual]]", | |
"action-transcode-reset": "reiniciar transcodificación", | |
diff --git a/i18n/qqq.json b/i18n/qqq.json | |
index 5d524022..e25b5732 100644 | |
--- a/i18n/qqq.json | |
+++ b/i18n/qqq.json | |
@@ -212,6 +212,9 @@ | |
"timedmedia-duration-hms": "Accessibility label for the duration of the media file, shown as a label on the placeholder to begin playback of the media file.\nParameters are:\n* $1 number of hours\n* $2 number of minutes\n* $3 number of seconds", | |
"timedmedia-duration-ms": "Accessibility label for the duration of the media file, shown as a label on the placeholder to begin playback of the media file.\nParameters are:\n* $1 number of minutes\n* $2 number of seconds", | |
"timedmedia-duration-s": "Accessibility label for the duration of the media file, shown as a label on the placeholder to begin playback of the media file.\nParameters are:\n* $1 number of seconds", | |
+ "timedmedia-preference-autoplayvideos": "Label in user preferences for a drop-down controlling the behavior of videos marked to play automatically.", | |
+ "timedmedia-preference-autoplayvideos-allow": "Videos marked to play automatically will start playing upon page load. One of the options for {{msg-mw|timedmedia-preference-autoplayvideos}}.", | |
+ "timedmedia-preference-autoplayvideos-never": "Videos marked to play automatically will require user interaction to start playing. One of the options for {{msg-mw|timedmedia-preference-autoplayvideos}}.", | |
"right-transcode-reset": "{{doc-right|transcode-reset}}", | |
"right-transcode-status": "{{doc-right|transcode-status}}", | |
"action-transcode-reset": "{{doc-action|transcode-reset}}", | |
diff --git a/includes/Hooks.php b/includes/Hooks.php | |
index 67314938..242cd541 100644 | |
--- a/includes/Hooks.php | |
+++ b/includes/Hooks.php | |
@@ -17,12 +17,14 @@ use MediaWiki\Hook\CanonicalNamespacesHook; | |
use MediaWiki\Hook\FileDeleteCompleteHook; | |
use MediaWiki\Hook\FileUndeleteCompleteHook; | |
use MediaWiki\Hook\FileUploadHook; | |
+use MediaWiki\Hook\MakeGlobalVariablesScriptHook; | |
use MediaWiki\Hook\PageMoveCompleteHook; | |
use MediaWiki\Hook\ParserTestGlobalsHook; | |
use MediaWiki\Hook\SkinTemplateNavigation__UniversalHook; | |
use MediaWiki\Hook\TitleMoveHook; | |
use MediaWiki\Linker\LinkRenderer; | |
use MediaWiki\Linker\LinkTarget; | |
+use MediaWiki\MediaWikiServices; | |
use MediaWiki\Output\Hook\BeforePageDisplayHook; | |
use MediaWiki\Output\OutputPage; | |
use MediaWiki\Page\Hook\ArticleFromTitleHook; | |
@@ -31,6 +33,7 @@ use MediaWiki\Page\Hook\ImageOpenShowImageInlineBeforeHook; | |
use MediaWiki\Page\Hook\ImagePageAfterImageLinksHook; | |
use MediaWiki\Page\Hook\ImagePageFileHistoryLineHook; | |
use MediaWiki\Page\Hook\RevisionFromEditCompleteHook; | |
+use MediaWiki\Preferences\Hook\GetPreferencesHook; | |
use MediaWiki\Revision\RevisionRecord; | |
use MediaWiki\SpecialPage\Hook\WgQueryPagesHook; | |
use MediaWiki\SpecialPage\SpecialPageFactory; | |
@@ -61,9 +64,11 @@ class Hooks implements | |
FileDeleteCompleteHook, | |
FileUndeleteCompleteHook, | |
FileUploadHook, | |
+ GetPreferencesHook, | |
ImageOpenShowImageInlineBeforeHook, | |
ImagePageAfterImageLinksHook, | |
ImagePageFileHistoryLineHook, | |
+ MakeGlobalVariablesScriptHook, | |
PageMoveCompleteHook, | |
ParserTestGlobalsHook, | |
RevisionFromEditCompleteHook, | |
@@ -478,6 +483,44 @@ class Hooks implements | |
} | |
} | |
+ /** | |
+ * @see https://www.mediawiki.org/wiki/Manual:Hooks/GetPreferences | |
+ * Register extension preferences | |
+ * @param User $user | |
+ * @param array &$prefs | |
+ */ | |
+ public function onGetPreferences( $user, &$prefs ) { | |
+ global $wgTmhEnableAutoPlayVideos; | |
+ | |
+ if ( $wgTmhEnableAutoPlayVideos === true ) { | |
+ $prefs['timedmediahandler-autoplayvideos'] = [ | |
+ 'type' => 'select', | |
+ 'label-message' => 'timedmedia-preference-autoplayvideos', | |
+ 'section' => 'rendering/files', | |
+ 'options-messages' => [ | |
+ 'timedmedia-preference-autoplayvideos-allow' => 'allow', | |
+ 'timedmedia-preference-autoplayvideos-never' => 'never', | |
+ ], | |
+ ]; | |
+ } | |
+ } | |
+ | |
+ /** | |
+ * @see https://www.mediawiki.org/wiki/Manual:Hooks/MakeGlobalVariablesScript | |
+ * Export variables which depend on the current user | |
+ * @param array &$vars | |
+ * @param OutputPage $out | |
+ * @return void | |
+ */ | |
+ public function onMakeGlobalVariablesScript( &$vars, $out ): void { | |
+ global $wgTmhEnableAutoPlayVideos; | |
+ | |
+ $user = $out->getUser(); | |
+ $userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup(); | |
+ $vars['wgTMHAutoplayVideos'] = $wgTmhEnableAutoPlayVideos && | |
+ $userOptionsLookup->getOption( $user, 'timedmediahandler-autoplayvideos' ) == 'allow'; | |
+ } | |
+ | |
/** | |
* @param array &$qp | |
*/ | |
diff --git a/includes/TimedMediaHandler.php b/includes/TimedMediaHandler.php | |
index 8ed12437..d77eab90 100644 | |
--- a/includes/TimedMediaHandler.php | |
+++ b/includes/TimedMediaHandler.php | |
@@ -38,6 +38,7 @@ class TimedMediaHandler extends MediaHandler { | |
'timedmedia_disablecontrols' => 'disablecontrols', | |
'timedmedia_loop' => 'loop', | |
'timedmedia_muted' => 'muted', | |
+ 'timedmedia_autoplay' => 'autoplay', | |
]; | |
} | |
@@ -134,6 +135,8 @@ class TimedMediaHandler extends MediaHandler { | |
* @return bool | |
*/ | |
public function normaliseParams( $image, &$params ) { | |
+ global $wgTmhEnableAutoPlayVideos; | |
+ | |
$timeParam = [ 'thumbtime', 'start', 'end' ]; | |
// Parse time values if endtime or thumbtime can't be more than length -1 | |
foreach ( $timeParam as $pn ) { | |
@@ -193,6 +196,18 @@ class TimedMediaHandler extends MediaHandler { | |
foreach ( [ 'loop', 'muted' ] as $flag ) { | |
$params[ $flag ] = isset( $params[ $flag ] ); | |
} | |
+ | |
+ // Autoplay only for video, since audio will likely be blocked | |
+ // by browsers | |
+ $params[ 'autoplay' ] = isset( $params[ 'autoplay' ] ) && | |
+ !$this->isAudio( $image ) && | |
+ ( $wgTmhEnableAutoPlayVideos === true ); | |
+ | |
+ // Autoplay videos must be muted | |
+ if ( $params[ 'autoplay' ] ) { | |
+ $params[ 'muted' ] = true; | |
+ } | |
+ | |
return true; | |
} | |
@@ -380,6 +395,7 @@ class TimedMediaHandler extends MediaHandler { | |
'loop' => $params['loop'] ?? false, | |
'muted' => $params['muted'] ?? false, | |
'inline' => $params['inline'] ?? false, | |
+ 'autoPlay' => $params['autoplay'] ?? false, | |
]; | |
// Allow start and end query string params on image pages (T203994) | |
diff --git a/includes/TimedMediaTransformOutput.php b/includes/TimedMediaTransformOutput.php | |
index 8a0ba68f..12e6f406 100644 | |
--- a/includes/TimedMediaTransformOutput.php | |
+++ b/includes/TimedMediaTransformOutput.php | |
@@ -64,6 +64,9 @@ class TimedMediaTransformOutput extends MediaTransformOutput { | |
/** @var bool */ | |
protected $loop; | |
+ /** @var bool */ | |
+ protected $autoPlay; | |
+ | |
// The prefix for player ids | |
private const PLAYER_ID_PREFIX = 'mwe_player_'; | |
@@ -89,6 +92,7 @@ class TimedMediaTransformOutput extends MediaTransformOutput { | |
$this->inline = $conf['inline'] ?? false; | |
$this->muted = $conf['muted'] ?? false; | |
$this->loop = $conf['loop'] ?? false; | |
+ $this->autoPlay = $conf['autoPlay'] ?? false; | |
} | |
/** | |
@@ -466,10 +470,19 @@ class TimedMediaTransformOutput extends MediaTransformOutput { | |
if ( $this->fillwindow ) { | |
$mediaAttr[ 'data-player' ] = 'fillwindow'; | |
} | |
- if ( $this->inline ) { | |
+ if ( $this->inline || $this->autoPlay ) { | |
$mediaAttr['class'] .= ' mw-tmh-inline'; | |
+ if ( $this->autoPlay ) { | |
+ // javascript will trigger the video playback with this class | |
+ $mediaAttr['class'] .= ' mw-tmh-autoplay'; | |
+ } | |
$mediaAttr['playsinline'] = ''; | |
- $mediaAttr['preload'] = 'auto'; | |
+ if ( $this->inline ) { | |
+ // autoplay will start playing when it gets on the viewport | |
+ // Do not preload it to prevent browsers from downloading | |
+ // a video that may never be viewed | |
+ $mediaAttr['preload'] = 'auto'; | |
+ } | |
} | |
// Used by Score extension and to disable specific controls from wikicode | |
diff --git a/resources/ext.tmh.player.element.js b/resources/ext.tmh.player.element.js | |
index e497bdf3..f4b932bd 100644 | |
--- a/resources/ext.tmh.player.element.js | |
+++ b/resources/ext.tmh.player.element.js | |
@@ -1,5 +1,14 @@ | |
const OgvJsSupport = require( 'ext.tmh.OgvJsSupport' ); | |
+/** | |
+ * Watches for autoplay videos entering or leaving the viewport, to play or | |
+ * pause them automatically | |
+ * | |
+ * @static | |
+ * @type {IntersectionObserver} | |
+ */ | |
+let lazyVideoObserver = null; | |
+ | |
function secondsToComponents( totalSeconds ) { | |
totalSeconds = parseInt( totalSeconds, 10 ); | |
const hours = Math.floor( totalSeconds / 3600 ); | |
@@ -54,6 +63,52 @@ function secondsToDurationLongString( totalSeconds ) { | |
return mw.msg( 'timedmedia-duration-s', seconds ); | |
} | |
+/** | |
+ * Checks video element visibility and play/pause them | |
+ * Only relevant for autoplay videos | |
+ * | |
+ * @param {IntersectionObserverEntry} entry | |
+ */ | |
+function playPauseVideosFromVisibility( entry ) { | |
+ const $element = $( entry.target ); | |
+ const mediaElement = $element.data( 'MediaElement' ); | |
+ const videojsPlayer = $element.data( 'videojsPlayer' ); | |
+ | |
+ if ( entry.isIntersecting ) { | |
+ if ( !videojsPlayer ) { | |
+ // Player not initialized | |
+ // Unobserve current element since it will be | |
+ // replaced by a cloned node | |
+ lazyVideoObserver.unobserve( entry.target ); | |
+ mediaElement.playInlineOrOpenDialog(); | |
+ } else if ( | |
+ videojsPlayer.paused() && | |
+ mediaElement.pausedByIntersectionObserver | |
+ ) { | |
+ videojsPlayer.play(); | |
+ mediaElement.pausedByIntersectionObserver = false; | |
+ } | |
+ } else { | |
+ if ( videojsPlayer && !videojsPlayer.paused() ) { | |
+ videojsPlayer.pause(); | |
+ mediaElement.pausedByIntersectionObserver = true; | |
+ } | |
+ } | |
+} | |
+ | |
+function initLazyVideoObserver() { | |
+ if ( lazyVideoObserver !== null ) { | |
+ return; | |
+ } | |
+ if ( 'IntersectionObserver' in window ) { | |
+ lazyVideoObserver = new IntersectionObserver( | |
+ function ( entries ) { | |
+ entries.forEach( playPauseVideosFromVisibility ); | |
+ } | |
+ ); | |
+ } | |
+} | |
+ | |
/** | |
* Main entry class for elements enhanced with videojs | |
* Provides page player loading, either with click-to-load dialog or inline mode | |
@@ -66,7 +121,14 @@ class MediaElement { | |
this.element = element; | |
this.$element = $( element ); | |
this.isAudio = element.tagName.toLowerCase() === 'audio'; | |
+ this.isAutoplayVideo = mw.config.get( 'wgTMHAutoplayVideos' ) === true && | |
+ !this.isAudio && | |
+ element.classList.contains( 'mw-tmh-autoplay' ); | |
this.$placeholder = null; | |
+ // This property gets set for autoplay videos when they were playing | |
+ // and went outside of the viewport. Need to differentiate from videos | |
+ // paused by the user | |
+ this.pausedByIntersectionObserver = false; | |
} | |
/** | |
@@ -92,7 +154,9 @@ class MediaElement { | |
id: $clonedVid.attr( 'id' ) + '_placeholder', | |
disabled: '', | |
tabindex: -1 | |
- } ).removeAttr( 'src' ); | |
+ } ) | |
+ .removeAttr( 'src' ) | |
+ .data( 'MediaElement', this ); | |
if ( !this.isAudio ) { | |
const aspectRatio = this.$element.attr( 'width' ) + ' / ' + this.$element.attr( 'height' ); | |
@@ -156,6 +220,12 @@ class MediaElement { | |
if ( playing ) { | |
this.playInlineOrOpenDialog(); | |
+ } else if ( this.isAutoplayVideo ) { | |
+ initLazyVideoObserver(); | |
+ // Autoplay videos will be handled by the intersection observer | |
+ if ( lazyVideoObserver !== null ) { | |
+ lazyVideoObserver.observe( $clonedVid[ 0 ] ); | |
+ } | |
} | |
} | |
@@ -244,10 +314,15 @@ class MediaElement { | |
* play the element in the dialog. | |
*/ | |
playInlineOrOpenDialog() { | |
- MediaElement.$interstitial = $( '<div>' ).addClass( 'mw-tmh-player-interstitial' ) | |
- .append( $( '<div>' ).addClass( 'mw-tmh-player-progress' ) | |
- .append( $( '<div>' ).addClass( 'mw-tmh-player-progress-bar' ) ) ) | |
- .appendTo( document.body ); | |
+ // Do not add a progress bar for inline player | |
+ if ( !this.isInline() ) { | |
+ MediaElement.$interstitial = $( '<div>' ).addClass( 'mw-tmh-player-interstitial' ) | |
+ .append( $( '<div>' ).addClass( 'mw-tmh-player-progress' ) | |
+ .append( $( '<div>' ).addClass( 'mw-tmh-player-progress-bar' ) ) ) | |
+ .appendTo( document.body ); | |
+ } else { | |
+ MediaElement.$interstitial = $(); | |
+ } | |
// If we're using ogv.js, we have to initialize the audio context | |
// during a click event to work on Safari, especially for iOS. | |
@@ -278,6 +353,7 @@ class MediaElement { | |
} | |
if ( this.isInline() ) { | |
+ const self = this; | |
mw.loader.using( 'ext.tmh.player.inline' ).then( () => { | |
this.$placeholder.find( 'a, .mw-tmh-label' ).detach(); | |
this.$placeholder.find( 'video,audio' ) | |
@@ -299,7 +375,21 @@ class MediaElement { | |
// Support: Edge 18 | |
setTimeout( () => { | |
MediaElement.$interstitial.detach(); | |
+ if ( self.isAutoplayVideo ) { | |
+ // Hides the control bar for autoplay videos when they | |
+ // start playing | |
+ videojsPlayer.userActive( false ); | |
+ } | |
videojsPlayer.play(); | |
+ if ( self.isAutoplayVideo && lazyVideoObserver !== null ) { | |
+ // References for IntersectionObserver | |
+ $( self.element ) | |
+ .data( 'videojsPlayer', videojsPlayer ) | |
+ .data( 'MediaElement', self ); | |
+ // Add the element to the IntersectionObserver to pause | |
+ // it when it goes outside of the viewport | |
+ lazyVideoObserver.observe( self.element ); | |
+ } | |
}, 0 ); | |
} ); | |
} ); | |
diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt | |
index ac4cba8a..4a98bc08 100644 | |
--- a/tests/parser/parserTests.txt | |
+++ b/tests/parser/parserTests.txt | |
@@ -240,6 +240,30 @@ wgParserEnableLegacyMediaDOM=false | |
<p><span class="mw-default-size" typeof="mw:File" data-mw='{"caption":"These are bogus."}'><span title="These are bogus."><video poster="http://example.com/images/thumb/0/00/Video.ogv/320px--Video.ogv.jpg" controls="" preload="none" muted="" loop="" height="240" width="320" resource="./File:Video.ogv" data-durationhint="5" class="mw-file-element"><source src="http://example.com/images/0/00/Video.ogv" type='video/ogg; codecs="theora"' data-file-width="320" data-file-height="240"/></video></span></span></p> | |
!! end | |
+!! test | |
+Video with flag autoplay but not enabled from config | |
+!! wikitext | |
+[[File:Video.ogv|autoplay|These are bogus.]] | |
+!! html/php | |
+<p><span class="mw-default-size" typeof="mw:File"><span><video id="mwe_player_1" poster="http://example.com/images/thumb/0/00/Video.ogv/320px--Video.ogv.jpg" controls="" preload="none" data-mw-tmh="" class="mw-file-element" width="320" height="240" data-durationhint="5" data-mwtitle="Video.ogv" data-mwprovider="local"><source src="http://example.com/images/0/00/Video.ogv" type="video/ogg; codecs="theora"" data-width="320" data-height="240" /></video></span></span> | |
+</p> | |
+!! html/parsoid | |
+<p><span class="mw-default-size" typeof="mw:File" data-parsoid='{"optList":[{"ck":"bogus","ak":"noplayer"},{"ck":"bogus","ak":"noicon"},{"ck":"bogus","ak":"disablecontrols=ok"},{"ck":"caption","ak":"These are bogus."}]}' data-mw='{"caption":"These are bogus."}'><span><video poster="http://example.com/images/thumb/0/00/Video.ogv/320px--Video.ogv.jpg" controls="" preload="none" height="240" width="320" resource="./File:Video.ogv"><source src="http://example.com/images/0/00/Video.ogv" type='video/ogg; codecs="theora"' data-file-width="320" data-file-height="240" data-title="Original Ogg file, 320 × 240 (590 kbps)" data-shorttitle="Ogg source"/></video></span></span></p> | |
+!! end | |
+ | |
+!! test | |
+Video with flag autoplay | |
+!! config | |
+wgTmhEnableAutoPlayVideos=true | |
+!! wikitext | |
+[[File:Video.ogv|autoplay|These are bogus.]] | |
+!! html/php | |
+<p><span class="mw-default-size" typeof="mw:File"><span><video id="mwe_player_1" poster="http://example.com/images/thumb/0/00/Video.ogv/320px--Video.ogv.jpg" controls="" preload="none" muted="" data-mw-tmh="" class="mw-tmh-inline mw-tmh-autoplay mw-file-element" width="320" height="240" playsinline="" data-durationhint="5" data-mwtitle="Video.ogv" data-mwprovider="local"><source src="http://example.com/images/0/00/Video.ogv" type="video/ogg; codecs="theora"" data-width="320" data-height="240" /></video></span></span> | |
+</p> | |
+!! html/parsoid | |
+<p><span class="mw-default-size" typeof="mw:File" data-parsoid='{"optList":[{"ck":"bogus","ak":"noplayer"},{"ck":"bogus","ak":"noicon"},{"ck":"bogus","ak":"disablecontrols=ok"},{"ck":"caption","ak":"These are bogus."}]}' data-mw='{"caption":"These are bogus."}'><span><video poster="http://example.com/images/thumb/0/00/Video.ogv/320px--Video.ogv.jpg" controls="" preload="none" height="240" width="320" resource="./File:Video.ogv"><source src="http://example.com/images/0/00/Video.ogv" type='video/ogg; codecs="theora"' data-file-width="320" data-file-height="240" data-title="Original Ogg file, 320 × 240 (590 kbps)" data-shorttitle="Ogg source"/></video></span></span></p> | |
+!! end | |
+ | |
## FIXME: Mock transcoding on the php side as well | |
!! test | |
Video with a transcoded source | |
diff --git a/tests/phpunit/mocks/MockOggHandler.php b/tests/phpunit/mocks/MockOggHandler.php | |
index 299d1f66..783a8650 100644 | |
--- a/tests/phpunit/mocks/MockOggHandler.php | |
+++ b/tests/phpunit/mocks/MockOggHandler.php | |
@@ -64,6 +64,7 @@ class MockOggHandler extends OggHandler { | |
'disablecontrols' => $params['disablecontrols'] ?? false, | |
'loop' => $params['loop'] ?? false, | |
'muted' => $params['muted'] ?? false, | |
+ 'autoPlay' => $params['autoplay'] ?? false, | |
]; | |
// No thumbs for audio |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment