Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ciencia/86edec03454a68e7b98320e165252513 to your computer and use it in GitHub Desktop.
Save ciencia/86edec03454a68e7b98320e165252513 to your computer and use it in GitHub Desktop.
patch MediaWiki extension TimedMediaHandler autoplay videos REL1_39
diff --git a/extension.json b/extension.json
index dc9cc247..d878a1ee 100644
--- a/extension.json
+++ b/extension.json
@@ -102,10 +102,12 @@
"CanonicalNamespaces": "main",
"FileDeleteComplete": "main",
"FileUpload": "main",
+ "GetPreferences": "main",
"ImageOpenShowImageInlineBefore": "main",
"ImagePageAfterImageLinks": "main",
"ImagePageFileHistoryLine": "main",
"LoadExtensionSchemaUpdates": "main",
+ "MakeGlobalVariablesScript": "main",
"MediaWikiPerformAction": "iframe",
"RevisionFromEditComplete": "main",
"ParserTestGlobals": "main",
@@ -306,8 +308,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"
+ },
"ResourceFileModulePaths": {
"localBasePath": "",
"remoteExtPath": "TimedMediaHandler"
diff --git a/i18n/TimedMediaHandler.i18n.magic.php b/i18n/TimedMediaHandler.i18n.magic.php
index 0c8a66c9..a90bb922 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 8f3aba6e..dead22d3 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -188,5 +188,8 @@
"videojs-captions-create": "Create captions",
"transcodestatistics": "Transcode statistics",
"timedmedia-timedtext-title-edit-subtitles": "$1 subtitles for clip: $2",
- "timedmedia-timedtext-title-create-subtitles": "No $1 subtitles were found for clip: $2"
+ "timedmedia-timedtext-title-create-subtitles": "No $1 subtitles were found for clip: $2",
+ "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"
}
diff --git a/i18n/es.json b/i18n/es.json
index a260ec6a..b3af4c5b 100644
--- a/i18n/es.json
+++ b/i18n/es.json
@@ -154,5 +154,8 @@
"videojs-more-information": "Más información",
"videojs-quality": "Calidad de vídeo",
"timedmedia-timedtext-title-edit-subtitles": "$1 subtítulos para el clip: $2",
- "timedmedia-timedtext-title-create-subtitles": "No se ha encontrado subtítulos $1 para el clip: $2"
+ "timedmedia-timedtext-title-create-subtitles": "No se ha encontrado subtítulos $1 para el clip: $2",
+ "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"
}
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 3d31c394..572f8b1b 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -209,5 +209,8 @@
"videojs-captions-create": "Menu entry in the captions menu of the video player, to navigate to the create captions interface. In some languages captions are known as subtitles.",
"transcodestatistics": "{{doc-special|TranscodeStatistics}}",
"timedmedia-timedtext-title-edit-subtitles": "$1 is language name for subtitles (e.g. \"English\"), $2 is title of file that timed text is for.\nShown as the page title on a TimedText namespace page when the page exists. See also {{msg-mw|timedmedia-timedtext-title-create-subtitles}}.",
- "timedmedia-timedtext-title-create-subtitles": "$1 is language name, $2 is title of file that timed text is for.\nShown as the page title on a TimedText namespace page when the page does not exist. See also {{msg-mw|timedmedia-timedtext-title-edit-subtitles}}."
+ "timedmedia-timedtext-title-create-subtitles": "$1 is language name, $2 is title of file that timed text is for.\nShown as the page title on a TimedText namespace page when the page does not exist. See also {{msg-mw|timedmedia-timedtext-title-edit-subtitles}}.",
+ "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}}."
}
diff --git a/includes/Hooks.php b/includes/Hooks.php
index 136a8cae..f77aedc0 100644
--- a/includes/Hooks.php
+++ b/includes/Hooks.php
@@ -17,6 +17,7 @@ use MediaWiki\Hook\BeforePageDisplayHook;
use MediaWiki\Hook\CanonicalNamespacesHook;
use MediaWiki\Hook\FileDeleteCompleteHook;
use MediaWiki\Hook\FileUploadHook;
+use MediaWiki\Hook\MakeGlobalVariablesScriptHook;
use MediaWiki\Hook\ParserTestGlobalsHook;
use MediaWiki\Hook\SkinTemplateNavigation__UniversalHook;
use MediaWiki\Hook\TitleMoveHook;
@@ -28,6 +29,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\TimedMediaHandler\WebVideoTranscode\WebVideoTranscode;
@@ -55,17 +57,18 @@ class Hooks implements
CanonicalNamespacesHook,
FileDeleteCompleteHook,
FileUploadHook,
+ GetPreferencesHook,
ImageOpenShowImageInlineBeforeHook,
ImagePageAfterImageLinksHook,
ImagePageFileHistoryLineHook,
LoadExtensionSchemaUpdatesHook,
+ MakeGlobalVariablesScriptHook,
ParserTestGlobalsHook,
RevisionFromEditCompleteHook,
SkinTemplateNavigation__UniversalHook,
TitleMoveHook,
WgQueryPagesHook
{
-
/**
* Register TimedMediaHandler namespace IDs
*
@@ -475,6 +478,44 @@ class Hooks implements
return true;
}
+ /**
+ * @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 e33d136e..d9cc76ab 100644
--- a/includes/TimedMediaHandler.php
+++ b/includes/TimedMediaHandler.php
@@ -39,6 +39,7 @@ class TimedMediaHandler extends MediaHandler {
'timedmedia_disablecontrols' => 'disablecontrols',
'timedmedia_loop' => 'loop',
'timedmedia_muted' => 'muted',
+ 'timedmedia_autoplay' => 'autoplay',
];
}
@@ -135,6 +136,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 ) {
@@ -194,6 +197,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;
}
@@ -389,6 +404,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 01d690cc..83ae1c81 100644
--- a/includes/TimedMediaTransformOutput.php
+++ b/includes/TimedMediaTransformOutput.php
@@ -62,6 +62,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_';
@@ -87,6 +90,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;
}
/**
@@ -455,10 +459,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
* Unmerged path jsdoc.json
diff --git a/resources/ext.tmh.player.element.js b/resources/ext.tmh.player.element.js
index 6cd6038d..1069bc9d 100644
--- a/resources/ext.tmh.player.element.js
+++ b/resources/ext.tmh.player.element.js
@@ -15,7 +15,14 @@ function MediaElement( element ) {
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;
}
/**
@@ -33,6 +40,15 @@ MediaElement.currentlyPlaying = false;
*/
MediaElement.$interstitial = null;
+/**
+ * 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 );
var hours = Math.floor( totalSeconds / 3600 );
@@ -86,6 +102,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 );
+ }
+ );
+ }
+}
+
/**
* Load our customizations for the media element,
* loading videojs inline or upon click inside a MediaDialog
@@ -108,7 +170,9 @@ MediaElement.prototype.load = function () {
id: $clonedVid.attr( 'id' ) + '_placeholder',
disabled: '',
tabindex: -1
- } ).removeAttr( 'src' );
+ } )
+ .removeAttr( 'src' )
+ .data( 'MediaElement', this );
if ( !this.isAudio ) {
var aspectRatio = this.$element.attr( 'width' ) + ' / ' + this.$element.attr( 'height' );
@@ -159,6 +223,12 @@ MediaElement.prototype.load = function () {
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 ] );
+ }
}
};
@@ -241,10 +311,13 @@ MediaElement.prototype.clickHandler = function ( event ) {
MediaElement.prototype.playInlineOrOpenDialog = function () {
var mediaElement = this;
- 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 );
+ }
// If we're using ogv.js, we have to initialize the audio context
// during a click event to work on Safari, especially for iOS.
@@ -275,6 +348,7 @@ MediaElement.prototype.playInlineOrOpenDialog = function () {
}
if ( this.isInline() ) {
+ const self = this;
mw.loader.using( 'ext.tmh.player.inline' ).then( function () {
mediaElement.$placeholder.find( 'a, .mw-tmh-label' ).detach();
mediaElement.$placeholder.find( 'video,audio' )
@@ -292,8 +366,21 @@ MediaElement.prototype.playInlineOrOpenDialog = function () {
// because some versions of EdgeHTML don't fire these events.
// Support: Edge 18
setTimeout( function () {
- 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 98299636..22e46cad 100644
--- a/tests/parser/parserTests.txt
+++ b/tests/parser/parserTests.txt
@@ -220,3 +220,51 @@ Video with flag muted and loop
!! html/parsoid
<p><span class="mw-default-size" typeof="mw:Video" 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 but not enabled from config
+!! wikitext
+[[File:Video.ogv|autoplay|These are bogus.]]
+!! html/php
+<p><video id="mwe_player_1" poster="http://example.com/images/thumb/0/00/Video.ogv/320px--Video.ogv.jpg" controls="" preload="none" 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=&quot;theora&quot;" data-title="Original Ogg file, 320 × 240 (590 kbps)" data-shorttitle="Ogg source" data-width="320" data-height="240" data-bandwidth="590013" data-framerate="30" /></video>
+</p>
+!! html/parsoid
+<p><span class="mw-default-size" typeof="mw:Video" 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><video id="mwe_player_1" poster="http://example.com/images/thumb/0/00/Video.ogv/320px--Video.ogv.jpg" controls="" preload="none" muted="" class="mw-tmh-inline mw-tmh-autoplay" 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=&quot;theora&quot;" data-title="Original Ogg file, 320 × 240 (590 kbps)" data-shorttitle="Ogg source" data-width="320" data-height="240" data-bandwidth="590013" data-framerate="30" /></video>
+</p>
+!! html/parsoid
+<p><span class="mw-default-size" typeof="mw:Video" 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
+!! config
+wgParserEnableLegacyMediaDOM=false
+!! wikitext
+[[File:Transcode.webm|thumb|Hello]]
+!! html/parsoid
+<figure class="mw-default-size" typeof="mw:File/Thumb"><span><video poster="http://example.com/images/thumb/0/09/Transcode.webm/180px--Transcode.webm.jpg" controls="" preload="none" height="132" width="180" resource="./File:Transcode.webm" data-durationhint="4" class="mw-file-element"><source src="http://example.com/images/0/09/Transcode.webm" type='video/webm; codecs="vp8, vorbis"' data-file-width="492" data-file-height="360"/><source src="http://example.com/images/transcoded/0/09/Transcode.webm/Transcode.webm.240p.vp9.webm" type='video/webm; codecs="vp9, opus"' data-width="328" data-height="240" data-transcodekey="240p.vp9.webm"/></video></span><figcaption>Hello</figcaption></figure>
+!! end
+
+!! test
+Video with markup in alt option
+!! config
+wgParserEnableLegacyMediaDOM=false
+!! wikitext
+[[File:Video.ogv|alt=testing '''bold''' in alt]]
+!! 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" 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=&quot;theora&quot;" data-title="Original Ogg file, 320 × 240 (590 kbps)" data-shorttitle="Ogg source" data-width="320" data-height="240" data-bandwidth="590013" data-framerate="30" /></video></span></span>
+</p>
+!! html/parsoid
+<p><span class="mw-default-size" typeof="mw:File mw:ExpandedAttrs" about="#mwt1" data-mw='{"attribs":[["alt",{"html":"alt=testing &lt;b data-parsoid=&apos;{\"dsr\":[29,39,3,3]}&apos;>bold&lt;/b> in alt","txt":"testing bold in alt"}]]}'><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" 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
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