r25050 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r25049‎ | r25050 | r25051 >
Date:13:50, 22 August 2007
Author:tstarling
Status:old
Tags:
Comment:
* Fix handling of $linkAttribs=false
* UI tweaks, not yet finalised: (none) option in player select, icon for audio
* (Bug 10950) Leave some vertical space in embedded objects for controls, for plugins where controls are likely to be added.
* Use innerHTML extensively, since document.createElement('object') is broken on several browsers.
Modified paths:
  • /trunk/extensions/OggHandler/OggHandler.i18n.php (modified) (history)
  • /trunk/extensions/OggHandler/OggHandler.php (modified) (history)
  • /trunk/extensions/OggHandler/OggHandler_body.php (modified) (history)
  • /trunk/extensions/OggHandler/OggPlayer.js (modified) (history)

Diff [purge]

Index: trunk/extensions/OggHandler/OggHandler.php
@@ -19,5 +19,7 @@
2020 $wgFFmpegLocation = 'ffmpeg';
2121 $wgExtensionMessagesFiles['OggHandler'] = "$oggDir/OggHandler.i18n.php";
2222 $wgParserOutputHooks['OggHandler'] = array( 'OggHandler', 'outputHook' );
 23+$wgCortadoJarFile = "cortado-ovt-debug-0.2.2.1-patched.jar";
 24+#$wgCortadoJarFile = "cortado-ovt-stripped-0.2.2.jar";
2325
2426 ?>
Index: trunk/extensions/OggHandler/OggPlayer.js
@@ -65,6 +65,7 @@
6666 break;
6767 default:
6868 elt.innerHTML = this.msg['ogg-no-player'] + '<br/>';
 69+ player = 'none';
6970 }
7071 if ( this.showPlayerSelect ) {
7172 elt.appendChild( document.createElement( 'br' ) );
@@ -116,17 +117,37 @@
117118 this.clientSupports['cortado'] = navigator.javaEnabled();
118119 },
119120
120 - 'makePlayerSelect' : function ( selectedPlayer, id, videoUrl, width, height, length ) {
121 - var select = document.createElement( 'select' );
122 - for ( var player in this.clientSupports ) {
 121+ 'addOption' : function ( select, value, text, selected ) {
123122 var option = document.createElement( 'option' );
124 - option.value = player;
125 - option.appendChild( document.createTextNode( this.msg['ogg-player-' + player] ) );
126 - if ( selectedPlayer == player ) {
 123+ option.value = value;
 124+ option.appendChild( document.createTextNode( text ) );
 125+ if ( selected ) {
127126 option.selected = true;
128127 }
129128 select.appendChild( option );
 129+ },
 130+
 131+ 'hx' : function ( s ) {
 132+ if ( typeof s != 'String' ) {
 133+ s = s.toString();
130134 }
 135+ return s.replace( /&/g, '&amp;' )
 136+ . replace( /</g, '&lt;' )
 137+ . replace( />/g, '&gt;' );
 138+ },
 139+
 140+ 'hq' : function ( s ) {
 141+ return '"' + this.hx( s ) + '"';
 142+ },
 143+
 144+ 'makePlayerSelect' : function ( selectedPlayer, id, videoUrl, width, height, length ) {
 145+ var select = document.createElement( 'select' );
 146+ if ( selectedPlayer == 'none' ) {
 147+ this.addOption( select, 'none', this.msg['ogg-player-none'], true );
 148+ }
 149+ for ( var player in this.clientSupports ) {
 150+ this.addOption( select, player, this.msg['ogg-player-' + player], selectedPlayer == player );
 151+ }
131152 select.value = selectedPlayer;
132153
133154 var me = this;
@@ -160,16 +181,16 @@
161182
162183 'embedVideoElement': function ( elt, videoUrl, width, height, length ) {
163184 var videoElt = document.createElement('video');
164 - videoElt.setAttribute('width', width);
165 - videoElt.setAttribute('height', height);
166 - videoElt.setAttribute('src', videoUrl);
167 - videoElt.setAttribute('autoplay', '1');
168 - videoElt.setAttribute('controls', '1');
169 - elt.appendChild(videoElt);
 185+ videoElt.setAttribute( 'width', width );
 186+ videoElt.setAttribute( 'height', height + 20 );
 187+ videoElt.setAttribute( 'src', videoUrl );
 188+ videoElt.setAttribute( 'autoplay', '1' );
 189+ videoElt.setAttribute( 'controls', '1' );
 190+ elt.appendChild( videoElt );
170191
171192 // Try to detect implementations that don't support controls
172193 // This works for the Opera test build
173 - if (!videoElt.controls) {
 194+ if ( !videoElt.controls ) {
174195 elt.appendChild( document.createElement( 'br' ) );
175196 elt.appendChild( this.newPlayButton( videoElt ) );
176197 elt.appendChild( this.newPauseButton( videoElt ) );
@@ -179,21 +200,25 @@
180201 },
181202
182203 'embedOggPlugin': function ( elt, videoUrl, width, height, length ) {
183 - var videoElt = document.createElement( 'object' );
184 - videoElt.setAttribute( 'type', 'application/ogg' );
185 - videoElt.setAttribute( 'width', width );
186 - videoElt.setAttribute( 'height', height );
187 - videoElt.setAttribute( 'data', videoUrl );
188 - elt.appendChild(videoElt);
 204+ var id = elt.id + "_obj";
 205+ elt.innerHTML +=
 206+ "<object id=" + this.hq( id ) +
 207+ " type='application/ogg'" +
 208+ " width=" + this.hq( width ) +
 209+ " height=" + this.hq( height + 20 ) +
 210+ " data=" + this.hq( videoUrl ) + "></object>";
189211 },
190212
191213 'embedVlcPlugin' : function ( elt, videoUrl, width, height, length ) {
192 - var videoElt = document.createElement( 'object' );
193 - videoElt.setAttribute( 'type', 'application/x-vlc-plugin' );
194 - videoElt.setAttribute( 'width', width );
195 - videoElt.setAttribute( 'height', height );
196 - videoElt.setAttribute( 'data', videoUrl );
197 - elt.appendChild(videoElt);
 214+ var id = elt.id + "_obj";
 215+ elt.innerHTML +=
 216+ "<object id=" + this.hq( id ) +
 217+ " type='application/x-vlc-plugin'" +
 218+ " width=" + this.hq( width ) +
 219+ " height=" + this.hq( height ) +
 220+ " data=" + this.hq( videoUrl ) + "></object>";
 221+
 222+ var videoElt = document.getElementById( id );
198223 elt.appendChild( document.createElement( 'br' ) );
199224 // TODO: seek bar
200225 elt.appendChild( this.newPlayButton( videoElt ) );
@@ -208,13 +233,13 @@
209234 // create this object with DOM functions. If anyone knows a better way
210235 // than innerHTML, please let me know. -- TS
211236 elt.innerHTML +=
212 - "<object id='" + id + "'" +
213 - " classid='clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921'" +
214 - " codebase='http://downloads.videolan.org/pub/videolan/vlc/latest/win32/axvlc.cab#Version=0,8,6,0'" +
215 - " width='" + width + "'" +
216 - " height='" + height + "'>" +
217 - "<param name='mrl' value='" + videoUrl.replace(/&/, '&amp;') + "'/>" +
218 - "</object>" ;
 237+ '<object id=' + this.hq( id ) +
 238+ ' classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921"' +
 239+ ' codebase="http://downloads.videolan.org/pub/videolan/vlc/latest/win32/axvlc.cab#Version=0,8,6,0"' +
 240+ ' width=' + this.hq( width ) +
 241+ ' height=' + this.hq( height ) + ">" +
 242+ '<param name="mrl" value=' + this.hq( videoUrl ) + '/>' +
 243+ '</object>' ;
219244
220245 var videoElt = document.getElementById( id );
221246 elt.appendChild( document.createElement( 'br' ) );
@@ -225,29 +250,34 @@
226251 },
227252
228253 'embedCortado' : function ( elt, videoUrl, width, height, length ) {
229 - var videoElt;
230 - if ( false ) {
231 - // Use <object>
232 - videoElt = document.createElement( 'object' );
233 - videoElt.setAttribute( 'codetype', 'application/x-java-applet' );
234 - videoElt.setAttribute( 'classid', 'com.fluendo.player.Cortado.class' );
235 - } else {
236 - // Use <applet>
237 - videoElt = document.createElement( 'applet' );
238 - videoElt.setAttribute( 'code', 'com.fluendo.player.Cortado.class' );
 254+ // Create the applet all at once
 255+ // In Opera, document.createElement('applet') immediately creates
 256+ // a non-working applet with unchangeable parameters, similar to the
 257+ // problem with IE and ActiveX.
 258+ elt.innerHTML =
 259+ '<applet code="com.fluendo.player.Cortado.class" ' +
 260+ ' width=' + this.hq( width ) +
 261+ ' height=' + this.hq( height + 18 ) +
 262+ ' archive=' + this.hq( this.cortadoUrl ) + '>' +
 263+ ' <param name="url" value=' + this.hq( videoUrl ) + '/>' +
 264+ ' <param name="duration" value=' + this.hq( length ) + '/>' +
 265+ ' <param name="seekable" value="true"/>' +
 266+ ' <param name="autoPlay" value="true"/>' +
 267+ ' <param name="showStatus" value="show"/>' +
 268+ ' <param name="statusHeight" value="18"/>' +
 269+ '</applet>';
 270+
 271+ // Disable autoPlay in the DOM right now, to prevent Mozilla from
 272+ // restarting an arbitrary number of applet instances on a back button click.
 273+ // Unfortunately this means that some clients (e.g. Opera) won't autoplay at all
 274+ var videoElt = elt.getElementsByTagName( 'applet' )[0];
 275+ var params = videoElt.getElementsByTagName( 'param' );
 276+ for ( var i = 0; i < params.length; i++ ) {
 277+ if ( params[i].name == 'autoPlay' ) {
 278+ params[i].value = '';
 279+ break;
 280+ }
239281 }
240 - videoElt.setAttribute( 'width', width );
241 - videoElt.setAttribute( 'height', height );
242 - videoElt.setAttribute( 'archive', this.cortadoUrl );
243 -
244 - var param = document.createElement( 'param' );
245 - this.addParam( videoElt, 'url', videoUrl );
246 - this.addParam( videoElt, 'duration', length );
247 - this.addParam( videoElt, 'seekable', 'true' );
248 - this.addParam( videoElt, 'autoPlay', 'true' );
249 - this.addParam( videoElt, 'showStatus', 'show' );
250 - this.addParam( videoElt, 'statusHeight', 18 );
251 - elt.appendChild( videoElt );
252282 },
253283
254284 'addParam': function ( elt, name, value ) {
@@ -257,6 +287,6 @@
258288 elt.appendChild( param );
259289 }
260290 };
261 -
262291
 292+// vim: ts=4 sw=4 noet cindent :
263293
Index: trunk/extensions/OggHandler/OggHandler_body.php
@@ -136,13 +136,14 @@
137137
138138 if ( $srcHeight == 0 || $srcWidth == 0 ) {
139139 // Make audio player
 140+ $icon = $file->iconThumb();
140141 if ( empty( $params['width'] ) ) {
141142 $width = 200;
142143 } else {
143144 $width = $params['width'];
144145 }
145 - $height = 20;
146 - return new OggAudioDisplay( $file->getURL(), $width, $height, $length );
 146+ $height = $icon->getHeight();
 147+ return new OggAudioDisplay( $file->getURL(), $icon->getUrl(), $width, $height, $length );
147148 }
148149
149150 if ( $flags & self::TRANSFORM_LATER ) {
@@ -308,7 +309,7 @@
309310 }
310311
311312 function setHeaders( $out ) {
312 - global $wgScriptPath;
 313+ global $wgScriptPath, $wgCortadoJarFile;
313314 if ( $out->hasHeadItem( 'OggHandler' ) ) {
314315 return;
315316 }
@@ -317,10 +318,10 @@
318319
319320 $msgNames = array( 'ogg-play', 'ogg-pause', 'ogg-stop', 'ogg-no-player',
320321 'ogg-player-videoElement', 'ogg-player-oggPlugin', 'ogg-player-cortado', 'ogg-player-vlcPlugin',
321 - 'ogg-player-vlcActiveX', 'ogg-using-player' );
 322+ 'ogg-player-vlcActiveX', 'ogg-player-none', 'ogg-using-player' );
322323 $msgValues = array_map( 'wfMsg', $msgNames );
323324 $jsMsgs = Xml::encodeJsVar( (object)array_combine( $msgNames, $msgValues ) );
324 - $encCortadoUrl = Xml::encodeJsVar( "$wgScriptPath/extensions/OggHandler/cortado-ovt-stripped-0.2.2.jar" );
 325+ $encCortadoUrl = Xml::encodeJsVar( "$wgScriptPath/extensions/OggHandler/$wgCortadoJarFile" );
325326
326327 $out->addHeadItem( 'OggHandler', <<<EOT
327328 <script type="text/javascript" src="$wgScriptPath/extensions/OggHandler/OggPlayer.js"></script>
@@ -355,19 +356,19 @@
356357
357358 function __construct( $videoUrl, $thumbUrl, $width, $height, $length, $isVideo ) {
358359 $this->videoUrl = $videoUrl;
359 - $this->thumbUrl = $thumbUrl;
 360+ $this->url = $thumbUrl;
360361 $this->width = round( $width );
361362 $this->height = round( $height );
362363 $this->length = round( $length );
363364 $this->isVideo = $isVideo;
364365 }
365366
366 - function toHtml( $attribs = array() , $linkAttribs = array() ) {
 367+ function toHtml( $attribs = array() , $linkAttribs = false ) {
367368 wfLoadExtensionMessages( 'OggHandler' );
368369
369370 OggTransformOutput::$serial++;
370371
371 - $encThumbUrl = htmlspecialchars( $this->thumbUrl );
 372+ $encThumbUrl = htmlspecialchars( $this->url );
372373
373374 if ( substr( $this->videoUrl, 0, 4 ) != 'http' ) {
374375 global $wgServer;
@@ -379,30 +380,31 @@
380381 $length = intval( $this->length );
381382 $width = intval( $this->width );
382383 $height = intval( $this->height );
 384+ $attribs['src'] = $this->url;
383385 if ( $this->isVideo ) {
384386 $msgStartPlayer = wfMsg( 'ogg-play-video' );
385 - $thumb =
386 - Xml::tags( 'a', $linkAttribs,
387 - Xml::element( 'img',
388 - array(
389 - 'src' => $this->thumbUrl,
390 - 'width' => $width,
391 - 'height' => $height,
392 - ) + $attribs,
393 - null )
394 - ) .
395 - "<br/>\n";
 387+ $attribs['width'] = $width;
 388+ $attribs['height'] = $height;
 389+ $playerHeight = $height;
396390 } else {
397391 $msgStartPlayer = wfMsg( 'ogg-play-sound' );
398 - $thumb = '';
 392+ $playerHeight = 0;
 393+ // Don't add width and height to the icon image, it won't match its true size
399394 }
 395+
 396+ $thumb = Xml::element( 'img', $attribs, null );
 397+ if ( $linkAttribs ) {
 398+ $thumb = Xml::tags( 'a', $linkAttribs, $thumb );
 399+ }
 400+ $thumb .= "<br/>\n";
 401+
400402 $id = "ogg_player_" . OggTransformOutput::$serial;
401403
402404 $s = Xml::tags( 'div', array( 'id' => $id ),
403405 $thumb .
404406 Xml::element( 'button',
405407 array(
406 - 'onclick' => "wgOggPlayer.init(false, '$id', $encUrl, $width, $height, $length);",
 408+ 'onclick' => "wgOggPlayer.init(false, '$id', $encUrl, $width, $playerHeight, $length);",
407409 ),
408410 $msgStartPlayer
409411 )
@@ -418,8 +420,8 @@
419421 }
420422
421423 class OggAudioDisplay extends OggTransformOutput {
422 - function __construct( $videoUrl, $width, $height, $length ) {
423 - parent::__construct( $videoUrl, false, $width, $height, $length, false );
 424+ function __construct( $videoUrl, $iconUrl, $width, $height, $length ) {
 425+ parent::__construct( $videoUrl, $iconUrl, $width, $height, $length, false );
424426 }
425427 }
426428
Index: trunk/extensions/OggHandler/OggHandler.i18n.php
@@ -15,12 +15,14 @@
1616 'ogg-stop' => 'Stop',
1717 'ogg-play-video' => 'Play video',
1818 'ogg-play-sound' => 'Play sound',
19 - 'ogg-no-player' => 'Sorry, no video player is available',
 19+ 'ogg-no-player' => 'Sorry, your system does not appear to have any supported player software. ' .
 20+ 'Please install <a href="http://www.java.com/en/download/manual.jsp">Java</a>.',
2021 'ogg-player-videoElement' => '<video> element',
2122 'ogg-player-oggPlugin' => 'Ogg plugin',
2223 'ogg-player-cortado' => 'Cortado (Java)',
2324 'ogg-player-vlcPlugin' => 'VLC (Mozilla)',
2425 'ogg-player-vlcActiveX' => 'VLC (ActiveX)',
 26+ 'ogg-player-none' => '(none)',
2527 'ogg-using-player' => 'Using player: ',
2628 ),
2729

Status & tagging log