r81832 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r81831‎ | r81832 | r81833 >
Date:18:52, 9 February 2011
Author:dale
Status:deferred
Tags:
Comment:
removed apiPlay Tracking
sync with local state
Modified paths:
  • /trunk/extensions/TimedMediaHandler/ApiPlayTracking (deleted) (history)
  • /trunk/extensions/TimedMediaHandler/EmbedPlayer/EmbedPlayer.resources.php (modified) (history)
  • /trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayer.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerGeneric.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerHtml.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerJava.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerKplayer.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerNative.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerVlc.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/EmbedPlayer/skins/kskin/mw.PlayerSkinKskin.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/EmbedPlayer/skins/mvpcf/mw.style.PlayerSkinMvpcf.css (modified) (history)
  • /trunk/extensions/TimedMediaHandler/EmbedPlayer/skins/mw.PlayerControlBuilder.js (modified) (history)

Diff [purge]

Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerGeneric.js
@@ -1,9 +1,9 @@
2 -/*
3 -* Simple embed object for unknown application/ogg plugin
 2+/*
 3+* Simple embed object for unknown application/ogg plugin
44 */
55 mw.EmbedPlayerGeneric = {
66 // List of supported features of the generic plugin
7 - supports: {
 7+ supports: {
88 'playHead':false,
99 'pause':false,
1010 'stop':true,
@@ -11,18 +11,18 @@
1212 'timeDisplay':false,
1313 'volumeControl':false
1414 },
15 -
16 - // Instance name:
 15+
 16+ // Instance name:
1717 instanceOf:'Generic',
18 -
 18+
1919 /*
2020 * Generic embed html
2121 *
2222 * @return {String}
23 - * embed code for generic ogg plugin
 23+ * embed code for generic ogg plugin
2424 */
2525 doEmbedHTML: function() {
26 - $j( this ).html(
 26+ $j( this ).html(
2727 '<object type="application/ogg" ' +
2828 'width="' + this.getWidth() + '" height="' + this.getHeight() + '" ' +
2929 'data="' + this.getSrc( this.seek_time_sec ) + '"></object>'
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayer.js
@@ -1,200 +1,201 @@
2 -/**
 2+/**
33 * embedPlayer is the base class for html5 video tag javascript abstraction library
44 * embedPlayer include a few subclasses:
5 -*
 5+*
66 * mediaPlayer Media player embed system ie: java, vlc or native.
7 -* mediaElement Represents source media elements
 7+* mediaElement Represents source media elements
88 * mw.PlayerControlBuilder Handles skinning of the player controls
99 */
1010
 11+mw.includeAllModuleMessages();
1112
1213 /*
1314 * The default video attributes supported by embedPlayer
14 -*/
 15+*/
1516 mw.setDefaultConfig( 'EmbedPlayer.Attributes', {
16 - /*
17 - * Base html element attributes:
18 - */
19 -
20 - // id: Auto-populated if unset
 17+ /*
 18+ * Base html element attributes:
 19+ */
 20+
 21+ // id: Auto-populated if unset
2122 "id" : null,
22 -
 23+
2324 // Width: alternate to "style" to set player width
2425 "width" : null,
25 -
 26+
2627 // Height: alternative to "style" to set player height
27 - "height" : null,
 28+ "height" : null,
2829
29 - /*
 30+ /*
3031 * Base html5 video element attributes / states
31 - * also see: http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html
 32+ * also see: http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html
3233 */
3334
3435 // Media src URI, can be relative or absolute URI
3536 "src" : null,
36 -
 37+
3738 // Poster attribute for displaying a place holder image before loading or playing the video
38 - "poster": null,
39 -
40 - // Autoplay if the media should start playing
 39+ "poster": null,
 40+
 41+ // Autoplay if the media should start playing
4142 "autoplay" : false,
42 -
 43+
4344 // Loop attribute if the media should repeat on complete
44 - "loop" : false,
45 -
 45+ "loop" : false,
 46+
4647 // If the player controls should be displayed
4748 "controls" : true,
48 -
49 - // Video starts "paused"
 49+
 50+ // Video starts "paused"
5051 "paused" : true,
51 -
52 - // ReadyState an attribute informs clients of video loading state:
53 - // see: http://www.whatwg.org/specs/web-apps/current-work/#readystate
54 - "readyState" : 0,
55 -
 52+
 53+ // ReadyState an attribute informs clients of video loading state:
 54+ // see: http://www.whatwg.org/specs/web-apps/current-work/#readystate
 55+ "readyState" : 0,
 56+
5657 // Loading state of the video element
5758 "networkState" : 0,
58 -
59 - // Current playback position
60 - "currentTime" :0,
61 -
 59+
 60+ // Current playback position
 61+ "currentTime" :0,
 62+
6263 // Previous player set time
6364 // Lets javascript use $j('#videoId').get(0).currentTime = newTime;
64 - "previousTime" :0,
65 -
 65+ "previousTime" :0,
 66+
6667 // Previous player set volume
6768 // Lets javascript use $j('#videoId').get(0).volume = newVolume;
68 - "previousVolume" : 1,
69 -
70 - // Initial player volume:
 69+ "previousVolume" : 1,
 70+
 71+ // Initial player volume:
7172 "volume" : 0.75,
72 -
 73+
7374 // Caches the volume before a mute toggle
74 - "preMuteVolume" : 0.75,
75 -
76 - // Media duration: Value is populated via
 75+ "preMuteVolume" : 0.75,
 76+
 77+ // Media duration: Value is populated via
7778 // custom durationHint attribute or via the media file once its played
78 - "duration" :null,
79 -
 79+ "duration" :null,
 80+
8081 // Mute state
8182 "muted" : false,
82 -
 83+
8384 /**
8485 * Custom attributes for embedPlayer player:
85 - * (not part of the html5 video spec)
 86+ * (not part of the html5 video spec)
8687 */
87 -
 88+
8889 // Default video aspect ratio
8990 'videoAspect': '4:3',
90 -
 91+
9192 // Start time of the clip
9293 "start" : 0,
93 -
 94+
9495 // End time of the clip
95 - "end" : null,
96 -
 96+ "end" : null,
 97+
9798 // A apiTitleKey for looking up subtitles, credits and related videos
9899 "apiTitleKey" : null,
99 -
 100+
100101 // The apiProvider where to lookup the title key
101102 "apiProvider" : null,
102 -
103 - // If the player controls should be overlaid
104 - //( Global default via config EmbedPlayer.OverlayControls in module loader.js)
 103+
 104+ // If the player controls should be overlaid
 105+ //( Global default via config EmbedPlayer.OverlayControls in module loader.js)
105106 "overlaycontrols" : true,
106 -
107 - // Attribute to use 'native' controls
 107+
 108+ // Attribute to use 'native' controls
108109 "usenativecontrols" : false,
109 -
 110+
110111 // If the player should include an attribution button:
111112 'attributionbutton' : true,
112 -
 113+
113114 // ROE url ( for xml based metadata )
114115 // also see: http://wiki.xiph.org/ROE
115116 "roe" : null,
116117
117118 // If serving an ogg_chop segment use this to offset the presentation time
118 - // ( for some plugins that use ogg page time rather than presentation time )
119 - "startOffset" : 0,
120 -
121 - // Thumbnail (same as poster)
 119+ // ( for some plugins that use ogg page time rather than presentation time )
 120+ "startOffset" : 0,
 121+
 122+ // Thumbnail (same as poster)
122123 "thumbnail" : null,
123 -
124 - // Source page for media asset ( used for linkbacks in remote embedding )
 124+
 125+ // Source page for media asset ( used for linkbacks in remote embedding )
125126 "linkback" : null,
126 -
 127+
127128 // If the download link should be shown
128129 "download_link" : true,
129 -
 130+
130131 // Content type of the media
131132 "type" : null
132133 });
133134
134 -mw.setDefaultConfig( {
 135+mw.setDefaultConfig( {
135136 // If the player controls should be overlaid on top of the video ( if supported by playback method)
136 - // can be set to false per embed player via overlayControls attribute
 137+ // can be set to false per embed player via overlayControls attribute
137138 'EmbedPlayer.OverlayControls' : true,
138 -
139 - 'EmbedPlayer.LibraryPage': 'http://www.kaltura.org/project/HTML5_Video_Media_JavaScript_Library',
140 -
 139+
 140+ 'EmbedPlayer.LibraryPage': 'http://www.kaltura.org/project/HTML5_Video_Media_JavaScript_Library',
 141+
141142 // A default apiProvider ( ie where to lookup subtitles, video properties etc )
142 - // NOTE: Each player instance can also specify a specific provider
 143+ // NOTE: Each player instance can also specify a specific provider
143144 "EmbedPlayer.ApiProvider" : "local",
144 -
145 - // Default video size ( if no size provided )
 145+
 146+ // Default video size ( if no size provided )
146147 "EmbedPlayer.DefaultSize" : "400x300",
147148
148 - // If the video player should attribute kaltura
 149+ // If the video player should attribute kaltura
149150 "EmbedPlayer.KalturaAttribution" : true,
150151
151152 // The attribution button
152153 'EmbedPlayer.AttributionButton' :{
153154 'title' : 'Kaltura html5 video library',
154 - 'href' : 'http://www.kaltura.org/project/HTML5_Video_Media_JavaScript_Library',
155 - // Style icon to be applied
156 - 'class' : 'kaltura-icon',
157 - // An icon image url ( should be a 12x12 image or data url )
158 - 'iconurl' : false
 155+ 'href' : 'http://www.kaltura.org/project/HTML5_Video_Media_JavaScript_Library',
 156+ // Style icon to be applied
 157+ 'class' : 'kaltura-icon',
 158+ // An icon image url ( should be a 12x12 image or data url )
 159+ 'iconurl' : false
159160 },
160161
161 -
162 - // Set the browser player warning flag displays warning for non optimal playback
 162+
 163+ // Set the browser player warning flag displays warning for non optimal playback
163164 "EmbedPlayer.ShowNativeWarning" : true,
164 -
165 - // If fullscreen is global enabled.
 165+
 166+ // If fullscreen is global enabled.
166167 "EmbedPlayer.EnableFullscreen" : true,
167 -
 168+
168169 // If mwEmbed should use the Native player controls
169170 // this will prevent video tag rewriting and skinning
170171 // useful for devices such as iPad / iPod that
171 - // don't fully support DOM overlays or don't expose full-screen
172 - // functionality to javascript
 172+ // don't fully support DOM overlays or don't expose full-screen
 173+ // functionality to javascript
173174 "EmbedPlayer.NativeControls" : false,
174 -
 175+
175176 // If mwEmbed should use native controls on mobile safari
176177 "EmbedPlayer.NativeControlsMobileSafari" : true,
177 -
178 -
179 - // The z-index given to the player interface during full screen ( high z-index )
 178+
 179+
 180+ // The z-index given to the player interface during full screen ( high z-index )
180181 "EmbedPlayer.fullScreenZIndex" : 999998,
181 -
 182+
182183 // The default share embed mode ( can be "object" or "videojs" )
183184 //
184185 // "object" will provide a <object tag pointing to mwEmbedFrame.php
185186 // Object embedding should be much more compatible with sites that
186187 // let users embed flash applets
187188 // "videojs" will include the source javascript and video tag to
188 - // rewrite the player on the remote page DOM
 189+ // rewrite the player on the remote page DOM
189190 // Video tag embedding is much more mash-up friendly but exposes
190 - // the remote site to the mwEmbed javascript and can be a xss issue.
 191+ // the remote site to the mwEmbed javascript and can be a xss issue.
191192 "EmbedPlayer.ShareEmbedMode" : 'object',
192 -
 193+
193194 // Default player skin name
194 - "EmbedPlayer.SkinName" : "mvpcf",
195 -
196 - // Number of milliseconds between interface updates
 195+ "EmbedPlayer.SkinName" : "mvpcf",
 196+
 197+ // Number of milliseconds between interface updates
197198 'EmbedPlayer.MonitorRate' : 250
198 -});
 199+} );
199200
200201 /**
201202 * The base source attribute checks
@@ -203,74 +204,74 @@
204205 mw.setDefaultConfig( 'embedPlayerSourceAttributes', [
205206 // source id
206207 'id',
207 -
 208+
208209 // media url
209210 'src',
210 -
211 - // media codecs attribute ( if provided )
 211+
 212+ // media codecs attribute ( if provided )
212213 'codecs',
213 -
214 - // Title string for the source asset
 214+
 215+ // Title string for the source asset
215216 'title',
216 -
 217+
217218 // boolean if we support temporal url requests on the source media
218 - 'URLTimeEncoding',
219 -
220 - // Media has a startOffset ( used for plugins that
221 - // display ogg page time rather than presentation time
 219+ 'URLTimeEncoding',
 220+
 221+ // Media has a startOffset ( used for plugins that
 222+ // display ogg page time rather than presentation time
222223 'startOffset',
223 -
 224+
224225 // A hint to the duration of the media file so that duration
225226 // can be displayed in the player without loading the media file
226227 'durationHint',
227 -
 228+
228229 // Media start time
229230 'start',
230 -
 231+
231232 // Media end time
232233 'end',
233 -
 234+
234235 // If the source is the default source
235236 'default',
236 -
 237+
237238 // Language key used for subtitle tracks
238239 'srclang',
239 -
240 - // titleKey ( used for api lookups )
 240+
 241+ // titleKey ( used for api lookups )
241242 'titleKey',
242 -
 243+
243244 // The provider type ( for what type of api query to make )
244245 'provider_type',
245 -
 246+
246247 // The api url for the provider
247 - 'provider_url'
 248+ 'provider_url'
248249 ] );
249250
250251 /**
251 -* Adds jQuery binding for embedPlayer
 252+* Adds jQuery binding for embedPlayer
252253 */
253254 ( function( $ ) {
254 -
 255+
255256 /*
256257 * embeds all players that match the rewrite player tags config
257 - * Passes off request to the embedPlayer selector:
258 - *
 258+ * Passes off request to the embedPlayer selector:
 259+ *
259260 * @param {Object} attributes Attributes to apply to embed players
260261 * @param {Function} callback Function to call once embedding is done
261262 */
262263 $.embedPlayers = function( attributes, callback) {
263264 $j( mw.getConfig( 'EmbedPlayer.RewriteTags' ) ).embedPlayer( attributes, callback );
264265 };
265 -
266 - /**
 266+
 267+ /**
267268 * Selector based embedPlayer jQuery binding
268269 *
269270 * Rewrites all tags via a given selector
270 - *
 271+ *
271272 * @param {object=} attributes Optional embedPlayer attributes for the given video interface.
272273 * Attributes Object can include any key value pair that would otherwise be
273 - * an attribute in the html element.
274 - *
 274+ * an attribute in the html element.
 275+ *
275276 * also see: mw.getConfig( 'EmbedPlayer.Attributes' )
276277 *
277278 * @param {Function=} callback Optional Function to be called once video interfaces are ready
@@ -279,31 +280,31 @@
280281 $.fn.embedPlayer = function( attributes, callback ) {
281282 mw.log( 'EmbedPlayer:: fn.embedPlayer' );
282283 var playerSelect = this.selector;
283 -
 284+
284285 // Define attributes if unset
285286 if( !attributes ) {
286287 attributes = {};
287288 }
288 -
 289+
289290 // Handle optional include of attributes argument:
290291 if( typeof attributes == 'function' ){
291292 callback = attributes;
292293 attributes = {};
293294 }
294 -
295 - $j( playerSelect ).each( function( index, playerElement) {
296 - // make sure the playerElement has an id:
 295+
 296+ $j( playerSelect ).each( function( index, playerElement) {
 297+ // make sure the playerElement has an id:
297298 if( $j( playerElement ).attr('id') =='' ){
298 - $j( playerElement ).attr( "id", 'mwe_v' + ( index ) );
 299+ $j( playerElement ).attr( "id", 'mwe_v' + ( index ) );
299300 }
300 -
301 - // If we are dynamically embedding on a "div" check if we can
 301+
 302+ // If we are dynamically embedding on a "div" check if we can
302303 // add a poster image behind the loader:
303 - if( playerElement.nodeName.toLowerCase() == 'div'
 304+ if( playerElement.nodeName.toLowerCase() == 'div'
304305 && ( attributes.poster || $j(playerElement).attr( 'poster' ) ) ){
305 - var posterSrc = ( attributes.poster ) ? attributes.poster : $j(playerElement).attr( 'poster' );
 306+ var posterSrc = ( attributes.poster ) ? attributes.poster : $j(playerElement).attr( 'poster' );
306307
307 - // Set image size:
 308+ // Set image size:
308309 var width = $j( playerElement ).width();
309310 var height = $j( playerElement ).height();
310311 if( !width ){
@@ -312,7 +313,7 @@
313314 if( !height ){
314315 var height = ( attributes.height )? attributes.height : '100%';
315316 }
316 -
 317+
317318 mw.log('EmbedPlayer:: set loading background: ' + posterSrc);
318319 $j( playerElement ).append(
319320 $j( '<img />' )
@@ -322,15 +323,15 @@
323324 'width' : width,
324325 'height' : height
325326 })
326 - );
 327+ );
327328 }
328329 });
329 -
330 - // If we have not detected browser plugin embed types do that now
 330+
 331+ // If we have not detected browser plugin embed types do that now
331332 if( ! mw.EmbedTypes.players ){
332333 mw.EmbedTypes.init();
333 - }
334 -
 334+ }
 335+
335336 // Create the Global Embed Player Manager ( if not already created )
336337 if( ! mw.playerManager ) {
337338 mw.log( "EmbedPlayer::Create the player manager:" );
@@ -338,31 +339,31 @@
339340 // Run the global hooks that mw.playerManager is ready
340341 mw.log( 'EmbedPlayer::trigger: EmbedPlayerManagerReady');
341342 $j( mw ).trigger( 'EmbedPlayerManagerReady' );
342 - }
 343+ }
343344 var addedToPlayerManager = false;
344 - // Make sure we have user preference setup ( for setting preferences on video selection )
345 - mw.setupUserConfig( function() {
346 - mw.log("EmbedPlayer:: found: " + $j( playerSelect ).length + ' players ');
347 - // Add each selected element to the player manager:
348 - $j( playerSelect ).each( function( index, playerElement) {
349 - // Make sure the video tag was not generated by our library:
 345+ // Make sure we have user preference setup ( for setting preferences on video selection )
 346+ mw.setupUserConfig( function() {
 347+ mw.log("EmbedPlayer:: found: " + $j( playerSelect ).length + ' players ');
 348+ // Add each selected element to the player manager:
 349+ $j( playerSelect ).each( function( index, playerElement) {
 350+ // Make sure the video tag was not generated by our library:
350351 if( $j( playerElement ).hasClass( 'nativeEmbedPlayerPid' ) ){
351 - $j('#loadingSpinner_' + $j( playerElement ).attr('id') ).hide();
352 - mw.log( 'EmbedPlayer::$j.embedPlayer skip embedPlayer gennerated video: ' + playerElement );
 352+ $j('#loadingSpinner_' + $j( playerElement ).attr('id') ).hide();
 353+ mw.log( 'EmbedPlayer::$j.embedPlayer skip embedPlayer gennerated video: ' + playerElement );
353354 } else {
354355 addedToPlayerManager = true;
355356 // Add the embedPlayer ready callback
356357 mw.playerManager.addCallback( callback );
357358 // Add the player
358359 mw.playerManager.addElement( playerElement, attributes);
359 - }
360 -
 360+ }
 361+
361362 } );
362 - // run the callback directly if no players were added to the playerManager
 363+ // run the callback directly if no players were added to the playerManager
363364 if( !addedToPlayerManager && callback ){
364365 callback();
365366 }
366 -
 367+
367368 });
368369 };
369370
@@ -371,46 +372,46 @@
372373 /**
373374 * EmbedPlayerManager
374375 *
375 -* Manages calls to embed video interfaces
 376+* Manages calls to embed video interfaces
376377 */
377378 var EmbedPlayerManager = function( ) {
378379 // Create a Player Manage
379380 return this.init( );
380381 };
381382 EmbedPlayerManager.prototype = {
382 -
 383+
383384 // Functions to run after the video interface is ready
384385 callbackFunctions : null,
385 -
 386+
386387 playerElementQueue: [],
387 -
 388+
388389 /**
389 - * Constructor initializes callbackFunctions and playerList
 390+ * Constructor initializes callbackFunctions and playerList
390391 */
391 - init: function( ) {
 392+ init: function( ) {
392393 this.callbackFunctions = [];
393394 this.playerList = [];
394395 },
395 -
 396+
396397 /**
397398 * Adds a callback to the callbackFunctions list
398399 * the callback functions are called once the players are ready.
399400 *
400 - * @param {Function} callback Function to be called once players are ready
 401+ * @param {Function} callback Function to be called once players are ready
401402 */
402403 addCallback: function( callback ) {
403404 if( typeof callback == 'function' ){
404405 this.callbackFunctions.push( callback );
405406 }
406407 },
407 -
 408+
408409 /**
409410 * Get the list of players
410411 */
411412 getPlayerList: function( ) {
412 - return this.playerList;
 413+ return this.playerList;
413414 },
414 -
 415+
415416 /**
416417 * Adds an Element for the embedPlayer to rewrite
417418 *
@@ -418,82 +419,82 @@
419420 * uses mvPlayList interface on playlist elements
420421 *
421422 * Once a player interface is established the following chain of functions are called;
422 - *
 423+ *
423424 * _this.checkPlayerSources()
424425 * _this.checkForTimedText()
425426 * _this.setupSourcePlayer()
426427 * _this.inheritEmbedPlayer()
427428 * _this.selectedPlayer.load()
428429 * _this.showPlayer()
429 - *
430 - * @param {Element} playerElement DOM element to be swapped
431 - * @param {Object} [Optional] attributes Extra attributes to apply to the player interface
 430+ *
 431+ * @param {Element} playerElement DOM element to be swapped
 432+ * @param {Object} [Optional] attributes Extra attributes to apply to the player interface
432433 */
433 - addElement: function( playerElement, attributes ) {
 434+ addElement: function( playerElement, attributes ) {
434435 var _this = this;
435 -
 436+
436437 if ( !playerElement.id || playerElement.id == '' ) {
437 - // give the playerElement an id:
438 - playerElement.id = 'vid' + ( this.playerList.length + 1 );
439 - }
 438+ // give the playerElement an id:
 439+ playerElement.id = 'vid' + ( this.playerList.length + 1 );
 440+ }
440441 mw.log('EmbedPlayerManager: addElement:: ' + playerElement.id );
441442
442443 // Add the element id to playerList
443 - this.playerList.push( playerElement.id );
444 -
445 - // Check for player attributes such as skins or plugins attributes
446 - // that add to the request set
 444+ this.playerList.push( playerElement.id );
 445+
 446+ // Check for player attributes such as skins or plugins attributes
 447+ // that add to the request set
447448 var playerDependencyRequest = [];
448 -
 449+
449450 // merge in any custom attributes
450451 $j.extend( playerElement, attributes );
451 -
452 - // Update the list of dependent libraries for the player
 452+
 453+ // Update the list of dependent libraries for the player
453454 // ( allows extensions to add to the dependency list )
454455 mw.embedPlayerUpdateLibraryRequest( playerElement, playerDependencyRequest );
455 -
 456+
456457 // Load any skins we need then swap in the interface
457458 mw.load( playerDependencyRequest, function() {
458459 var waitForMeta = true;
459 -
460 - // Be sure to "stop" the target ( sometimes firefox keeps playing the video even
461 - // though its been removed from the DOM )
 460+
 461+ // Be sure to "stop" the target ( sometimes firefox keeps playing the video even
 462+ // though its been removed from the DOM )
462463 if( playerElement.pause ){
463464 playerElement.pause();
464465 }
465 -
466 -
 466+
 467+
467468 // Let extensions determine if its worthwhile to wait for metadata:
468 - // We pass an object to the trigger to preserve reference values
469 - var eventObject = {
470 - 'playerElement' : playerElement,
 469+ // We pass an object to the trigger to preserve reference values
 470+ var eventObject = {
 471+ 'playerElement' : playerElement,
471472 'waitForMeta' : waitForMeta
472 - };
 473+ };
473474 $j( mw ).trigger( 'addElementWaitForMetaEvent', eventObject );
474 -
475 - // update the waitForMeta
 475+
 476+ // update the waitForMeta
476477 waitForMeta = eventObject[ 'waitForMeta' ];
477 -
478 -
 478+
 479+
479480 // Set the wait for meta flag if unset by extension
480481 if( waitForMeta ){
481482 waitForMeta = _this.waitForMetaCheck( playerElement );
482483 }
483 -
484 - var ranPlayerSwapFlag = false;
485 -
 484+
 485+ var ranPlayerSwapFlag = false;
 486+
486487 // Local callback to runPlayer swap once playerElement has metadata
487488 function runPlayerSwap() {
488489 if( ranPlayerSwapFlag ){
489 - return ;
 490+ return ;
490491 }
491 - ranPlayerSwapFlag = true;
 492+ ranPlayerSwapFlag = true;
492493 mw.log("EmbedPlayer::runPlayerSwap::" + $j( playerElement ).attr('id') );
493 -
494 - var playerInterface = new mw.EmbedPlayer( playerElement , attributes);
495 - var swapPlayer = _this.swapEmbedPlayerElement( playerElement, playerInterface );
496 -
497 - // Copy over any data attributes from the playerElement
 494+
 495+ var playerInterface = new mw.EmbedPlayer( playerElement , attributes);
 496+ var swapPlayer = _this.swapEmbedPlayerElement( playerElement, playerInterface );
 497+
 498+ // Copy over any data attributes from the playerElement
498499 if( mw.getConfig( 'EmbedPlayer.DataAttributes' ) ) {
499500 var dataAttr = mw.getConfig( 'EmbedPlayer.DataAttributes' );
500501 for( var i in dataAttr ){
@@ -502,45 +503,45 @@
503504 }
504505 }
505506 }
506 -
 507+
507508 // Pass the id to any hook that needs to interface prior to checkPlayerSources
508509 mw.log("EmbedPlayer::addElement :trigger " + playerInterface.id );
509510 $j( mw ).trigger ( 'newEmbedPlayerEvent', $j( '#' + playerInterface.id ).get(0) );
510 -
 511+
511512 // Issue the checkPlayerSources call to the new player interface:
512 - // make sure to use the element that is in the DOM:
513 - $j( '#' + playerInterface.id ).get(0).checkPlayerSources();
 513+ // make sure to use the element that is in the DOM:
 514+ $j( '#' + playerInterface.id ).get(0).checkPlayerSources();
514515 }
515 -
516 - if( waitForMeta ) {
517 - mw.log('EmbedPlayer::WaitForMeta ( video missing height (' +
518 - $j( playerElement ).attr('height') + '), width (' +
 516+
 517+ if( waitForMeta ) {
 518+ mw.log('EmbedPlayer::WaitForMeta ( video missing height (' +
 519+ $j( playerElement ).attr('height') + '), width (' +
519520 $j( playerElement ).attr('width') + ') or duration: ' +
520 - $j( playerElement ).attr('duration')
 521+ $j( playerElement ).attr('duration')
521522 );
522 -
 523+
523524 playerElement.removeEventListener( "loadedmetadata", runPlayerSwap, true );
524525 playerElement.addEventListener( "loadedmetadata", runPlayerSwap, true );
525 -
 526+
526527 // Time-out of 5 seconds ( maybe still playable but no timely metadata )
527528 setTimeout( runPlayerSwap, 5000 );
528529 return ;
529 - } else {
 530+ } else {
530531 runPlayerSwap();
531532 return ;
532 - }
533 - });
 533+ }
 534+ });
534535 },
535 -
536 - /**
537 - * Check for bogus resolutions of the media asset that has not loaded.
538 - * @return
539 - * true if the resolution is "likely" to be updated
 536+
 537+ /**
 538+ * Check for bogus resolutions of the media asset that has not loaded.
 539+ * @return
 540+ * true if the resolution is "likely" to be updated
540541 * by waiting for metadata
541542 * false if the resolution has been set via an attribute or is already loaded
542 - */
 543+ */
543544 waitForMetaCheck: function( playerElement ){
544 - var waitForMeta = false;
 545+ var waitForMeta = false;
545546 if( !playerElement )
546547 return ;
547548 // If we don't have a native player don't wait for metadata
@@ -548,156 +549,156 @@
549550 !mw.EmbedTypes.players.isSupportedPlayer( 'h264Native' ) )
550551 {
551552 return false;
552 - }
553 -
554 -
 553+ }
 554+
 555+
555556 var width = $j( playerElement ).css( 'width' );
556557 var height = $j( playerElement ).css( 'height' );
557 -
558 - // Css video defaults
559 - if( $j( playerElement ).css( 'width' ) == '300px' &&
 558+
 559+ // Css video defaults
 560+ if( $j( playerElement ).css( 'width' ) == '300px' &&
560561 $j( playerElement ).css( 'height' ) == '150px'
561562 ){
562563 waitForMeta = true;
563 - } else {
564 - // Check if we should wait for duration:
565 - if( $j( playerElement ).attr( 'duration') ||
 564+ } else {
 565+ // Check if we should wait for duration:
 566+ if( $j( playerElement ).attr( 'duration') ||
566567 $j( playerElement ).attr('durationHint')
567568 ){
568569 // height, width and duration set; do not wait for meta data:
569570 return false;
570 - } else {
 571+ } else {
571572 waitForMeta = true;
572573 }
573574 }
574 -
 575+
575576 //Firefox ~ sometimes ~ gives -1 for unloaded media
576577 if ( $j(playerElement).attr( 'width' ) == -1 || $j(playerElement).attr( 'height' ) == -1 ) {
577 - waitForMeta = true;
 578+ waitForMeta = true;
578579 }
579 -
 580+
580581 // Google Chrome / safari gives 0 width height for unloaded media
581 - if( $j(playerElement).attr( 'width' ) === 0 ||
582 - $j(playerElement).attr( 'height' ) === 0
 582+ if( $j(playerElement).attr( 'width' ) === 0 ||
 583+ $j(playerElement).attr( 'height' ) === 0
583584 ) {
584585 waitForMeta = true;
585586 }
586 -
 587+
587588 // Firefox default width height is ~sometimes~ 150 / 300
588589 if( this.height == 150 && this.width == 300 ){
589 - waitForMeta = true;
590 - }
591 -
592 - // Make sure we have a src attribute or source child
 590+ waitForMeta = true;
 591+ }
 592+
 593+ // Make sure we have a src attribute or source child
593594 // ( i.e not a video tag to be dynamically populated or looked up from xml resource description )
594 - if( waitForMeta &&
 595+ if( waitForMeta &&
595596 (
596597 $j( playerElement ).attr('src') ||
597 - $j( playerElement ).find("source[src]").length !== 0
 598+ $j( playerElement ).find("source[src]").length !== 0
598599 )
599600 ) {
600 - // Detect src type ( if no type set )
 601+ // Detect src type ( if no type set )
601602 return true;
602 - } else {
 603+ } else {
603604 // playerElement is not likely to update its meta data ( no src )
604605 return false;
605 - }
 606+ }
606607 },
607 -
 608+
608609 /**
609610 * swapEmbedPlayerElement
610611 *
611612 * Takes a video element as input and swaps it out with
612613 * an embed player interface
613614 *
614 - * @param {Element} targetElement Element to be swapped
 615+ * @param {Element} targetElement Element to be swapped
615616 * @param {Object} playerInterface Interface to swap into the target element
616617 */
617 - swapEmbedPlayerElement: function( targetElement, playerInterface ) {
 618+ swapEmbedPlayerElement: function( targetElement, playerInterface ) {
618619 mw.log( 'EmbedPlayer::swapEmbedPlayerElement: ' + targetElement.id );
619620 // Create a new element to swap the player interface into
620 - var swapPlayerElement = document.createElement('div');
621 -
 621+ var swapPlayerElement = document.createElement('div');
 622+
622623 // Get properties / methods from playerInterface
623 - for ( var method in playerInterface ) {
624 - if ( method != 'readyState' ) { // readyState crashes IE ( don't include )
 624+ for ( var method in playerInterface ) {
 625+ if ( method != 'readyState' ) { // readyState crashes IE ( don't include )
625626 swapPlayerElement[ method ] = playerInterface[ method ];
626627 }
627628 }
628 -
 629+
629630 // Check if we are using native controls ( should keep the video embed around )
630631 if( playerInterface.useNativePlayerControls() ) {
631632 $j( targetElement )
632633 .attr( 'id', playerInterface.pid )
633634 .addClass( 'nativeEmbedPlayerPid' )
634635 .show()
635 - .after(
 636+ .after(
636637 $j( swapPlayerElement ).css( 'display', 'none' )
637638 );
638639 } else {
639640 $j( targetElement ).replaceWith( swapPlayerElement );
640641 }
641 -
642 -
643 - // Set swapPlayerElement has height / width set and set to loading:
644 - $j( swapPlayerElement ).css( {
645 - 'width' : playerInterface.width + 'px',
646 - 'height' : playerInterface.height + 'px'
 642+
 643+
 644+ // Set swapPlayerElement has height / width set and set to loading:
 645+ $j( swapPlayerElement ).css( {
 646+ 'width' : playerInterface.width,
 647+ 'height' : playerInterface.height
647648 } );
648 -
649 - // If we don't already have a loadSpiner add one:
 649+
 650+ // If we don't already have a loadSpiner add one:
650651 if( $j('#loadingSpinner_' + playerInterface.id ).length == 0 ){
651652 if( playerInterface.useNativePlayerControls() ) {
652653 $j( targetElement )
653654 .getAbsoluteOverlaySpinner()
654655 .attr('id', 'loadingSpinner_' + playerInterface.id );
655656 }else{
656 - $j( swapPlayerElement ).append(
 657+ $j( swapPlayerElement ).append(
657658 $j('<div />')
658 - .loadingSpinner()
 659+ .loadingSpinner()
659660 );
660661 }
661662 }
662663 return swapPlayerElement;
663664 },
664 -
665 -
 665+
 666+
666667 /**
667 - * Player ready will run the global callbacks
 668+ * Player ready will run the global callbacks
668669 * once players are "ready"
669 - *
670 - * This enables mw.ready event to expose video tag
671 - * elements as if the videotag was supported natively.
672670 *
 671+ * This enables mw.ready event to expose video tag
 672+ * elements as if the videotag was supported natively.
 673+ *
673674 * @param {Object} player The EmbedPlayer object
674675 */
675676 playerReady: function( player ) {
676677 var _this = this;
677 - mw.log( 'EmbedPlayer::ReadyToPlay callback player:' + player.id );
 678+ mw.log( 'EmbedPlayer::ReadyToPlay callback player:' + player.id );
678679 player.readyToPlay = true;
679 -
 680+
680681 // Remove the player loader spinner:
681682 $j('#loadingSpinner_' + player.id ).remove();
682 -
683 - // Run the player ready trigger
 683+
 684+ // Run the player ready trigger
684685 $j( player ).trigger( 'playerReady' );
685 -
686 - var is_ready = true;
 686+
 687+ var is_ready = true;
687688 for ( var i = 0; i < this.playerList.length; i++ ) {
688 - var currentPlayer = $j( '#' + this.playerList[i] ).get( 0 );
 689+ var currentPlayer = $j( '#' + this.playerList[i] ).get( 0 );
689690 if ( player ) {
690 - // Check if the current video is ready ( or has an error out )
691 - is_ready = ( player.readyToPlay || player.loadError ) ? is_ready : false;
 691+ // Check if the current video is ready ( or has an error out )
 692+ is_ready = ( player.readyToPlay || player.loadError ) ? is_ready : false;
692693 }
693694 }
694695 if ( is_ready ) {
695696 // Be sure to remove any player loader spinners
696697 $j('.playerLoadingSpinner').remove();
697 -
698 - mw.log( "EmbedPlayer::All on-page players ready run playerMannager callbacks" );
699 - // Run queued functions
 698+
 699+ mw.log( "EmbedPlayer::All on-page players ready run playerManager callbacks" );
 700+ // Run queued functions
700701 if( _this.callbackFunctions ) {
701 - while ( _this.callbackFunctions.length ) {
 702+ while ( _this.callbackFunctions.length ) {
702703 _this.callbackFunctions.shift()();
703704 }
704705 }
@@ -717,70 +718,70 @@
718719 mediaSource.prototype = {
719720 // MIME type of the source.
720721 mimeType:null,
721 -
 722+
722723 // URI of the source.
723724 uri:null,
724 -
 725+
725726 // Title of the source.
726727 title: null,
727 -
 728+
728729 // True if the source has been marked as the default.
729730 markedDefault: false,
730 -
731 - // True if the source supports url specification of offset and duration
 731+
 732+ // True if the source supports url specification of offset and duration
732733 URLTimeEncoding:false,
733 -
734 - // Start offset of the requested segment
 734+
 735+ // Start offset of the requested segment
735736 startOffset: 0,
736 -
737 - // Duration of the requested segment (0 if not known)
 737+
 738+ // Duration of the requested segment (0 if not known)
738739 duration:0,
739 -
 740+
740741 // Is the source playable
741742 is_playable: null,
742 -
 743+
743744 // source id
744745 id: null,
745 -
 746+
746747 // Start time in npt format
747748 start_npt: null,
748 -
 749+
749750 // End time in npt format
750751 end_npt: null,
751 -
752 - // A provider "id" to identify api request type
 752+
 753+ // A provider "id" to identify api request type
753754 provider_type : null,
754755
755756 // The api url for the provider
756 - provider_url : null,
757 -
 757+ provider_url : null,
 758+
758759 /**
759760 * MediaSource constructor:
760761 */
761 - init : function( element ) {
 762+ init : function( element ) {
762763 // mw.log('EmbedPlayer::adding mediaSource: ' + element);
763 - this.src = $j( element ).attr( 'src' );
764 -
765 - // Set default URLTimeEncoding if we have a time url:
766 - // not ideal way to discover if content is on an oggz_chop server.
767 - // should check some other way.
 764+ this.src = $j( element ).attr( 'src' );
 765+
 766+ // Set default URLTimeEncoding if we have a time url:
 767+ // not ideal way to discover if content is on an oggz_chop server.
 768+ // should check some other way.
768769 var pUrl = mw.parseUri ( this.src );
769770 if ( typeof pUrl[ 'queryKey' ][ 't' ] != 'undefined' ) {
770771 this.URLTimeEncoding = true;
771772 }
772 -
 773+
773774 var sourceAttr = mw.getConfig( 'embedPlayerSourceAttributes' );
774 -
 775+
775776 for ( var i = 0; i < sourceAttr.length; i++ ) { // array loop:
776777 var attr = sourceAttr[ i ];
777778 var attr_value = element.getAttribute( attr );
778779 if ( attr_value ) {
779 - this[ attr ] = attr_value;
 780+ this[ attr ] = attr_value;
780781 }
781782 }
782 -
783 -
784 - // Set the content type:
 783+
 784+
 785+ // Set the content type:
785786 if ( $j( element ).attr( 'type' ) ) {
786787 this.mimeType = $j( element ).attr( 'type' );
787788 }else if ( $j( element ).attr( 'content-type' ) ) {
@@ -791,41 +792,41 @@
792793 } else {
793794 this.mimeType = this.detectType( this.src );
794795 }
795 -
 796+
796797 // Conform the mime type to ogg
797798 if( this.mimeType == 'video/theora') {
798799 this.mimeType = 'video/ogg';
799800 }
800 -
 801+
801802 if( this.mimeType == 'audio/vorbis') {
802803 this.mimeType = 'audio/ogg';
803804 }
804 -
 805+
805806 // Check for parent elements ( supplies categories in "track" )
806 - if( $j( element ).parent().attr('category') ) {
807 - this.category = $j( element ).parent().attr('category');
 807+ if( $j( element ).parent().attr('category') ) {
 808+ this.category = $j( element ).parent().attr('category');
808809 }
809 -
 810+
810811 if( $j( element ).attr( 'default' ) ){
811812 this.markedDefault = true;
812813 }
813 -
 814+
814815 // Get the url duration ( if applicable )
815816 this.getURLDuration();
816817 },
817 -
 818+
818819 /**
819820 * Update Source title via Element
820821 * @param {Element} element Source element to update attributes from
821822 */
822823 updateSource: function( element ) {
823 - // for now just update the title:
 824+ // for now just update the title:
824825 if ( $j( element ).attr( "title" ) ) {
825826 this.title = $j( element ).attr( "title" );
826827 }
827828 },
828 -
829 - /**
 829+
 830+ /**
830831 * Updates the src time and start & end
831832 * @param {String} start_time: in NPT format
832833 * @param {String} end_time: in NPT format
@@ -835,26 +836,26 @@
836837 // mw.log("pre uri:" + this.src);
837838 // if we have time we can use:
838839 if ( this.URLTimeEncoding ) {
839 - // make sure its a valid start time / end time (else set default)
 840+ // make sure its a valid start time / end time (else set default)
840841 if ( !mw.npt2seconds( start_npt ) ) {
841842 start_npt = this.start_npt;
842843 }
843 -
 844+
844845 if ( !mw.npt2seconds( end_npt ) ) {
845846 end_npt = this.end_npt;
846847 }
847 -
848 - this.src = mw.replaceUrlParams( this.src, {
849 - 't': start_npt + '/' + end_npt
 848+
 849+ this.src = mw.replaceUrlParams( this.src, {
 850+ 't': start_npt + '/' + end_npt
850851 });
851 -
 852+
852853 // update the duration
853854 this.getURLDuration();
854855 }
855856 },
856 -
 857+
857858 /**
858 - * Sets the duration and sets the end time if unset
 859+ * Sets the duration and sets the end time if unset
859860 * @param {Float} duration: in seconds
860861 */
861862 setDuration: function ( duration ) {
@@ -863,8 +864,8 @@
864865 this.end_npt = mw.seconds2npt( this.startOffset + duration );
865866 }
866867 },
867 -
868 - /**
 868+
 869+ /**
869870 * MIME type accessors function.
870871 * @return {String} the MIME type of the source.
871872 */
@@ -875,9 +876,9 @@
876877 this.mimeType = this.detectType( this.src );
877878 return this.mimeType;
878879 },
879 -
 880+
880881 /** URI function.
881 - * @param {Number} serverSeekTime Int: Used to adjust the URI for url based seeks)
 882+ * @param {Number} serverSeekTime Int: Used to adjust the URI for url based seeks)
882883 * @return {String} the URI of the source.
883884 */
884885 getSrc : function( serverSeekTime ) {
@@ -890,21 +891,21 @@
891892 }
892893 return mw.replaceUrlParams( this.src,
893894 {
894 - 't': mw.seconds2npt( serverSeekTime ) + endvar
895 - }
896 - );
 895+ 't' : mw.seconds2npt( serverSeekTime ) + endvar
 896+ }
 897+ );
897898 },
898 -
899 - /**
 899+
 900+ /**
900901 * Title accessor function.
901902 * @return {String} Title of the source.
902903 */
903 - getTitle : function() {
 904+ getTitle : function() {
904905 if( this.title ){
905906 return this.title;
906907 }
907 -
908 - // Return a Title based on mime type:
 908+
 909+ // Return a Title based on mime type:
909910 switch( this.getMIMEType() ) {
910911 case 'video/h264' :
911912 return gM( 'mwe-embedplayer-video-h264' );
@@ -925,25 +926,25 @@
926927 return 'AVI video'; // FIXME: i18n
927928 break;
928929 }
929 -
930 - // Return tilte based on file name:
 930+
 931+ // Return Title based on file name:
931932 var urlParts = mw.parseUri( this.getSrc() );
932933 if( urlParts.file ){
933934 return urlParts.file;
934935 }
935 -
 936+
936937 // Return the mime type string if not known type.
937938 return this.mimeType;
938939 },
939 -
940 - /**
941 - *
 940+
 941+ /**
 942+ *
942943 * Get Duration of the media in milliseconds from the source url.
943944 *
944945 * Supports media_url?t=ntp_start/ntp_end url request format
945946 */
946947 getURLDuration : function() {
947 - // check if we have a URLTimeEncoding:
 948+ // check if we have a URLTimeEncoding:
948949 if ( this.URLTimeEncoding ) {
949950 var annoURL = mw.parseUri( this.src );
950951 if ( annoURL.queryKey.t ) {
@@ -954,7 +955,7 @@
955956 this.duration = mw.npt2seconds( this.end_npt ) - this.startOffset;
956957 } else {
957958 // look for this info as attributes
958 - if ( this.startOffset ) {
 959+ if ( this.startOffset ) {
959960 this.start_npt = mw.seconds2npt( this.startOffset );
960961 }
961962 if ( this.duration ) {
@@ -963,8 +964,8 @@
964965 }
965966 }
966967 },
967 -
968 - /**
 968+
 969+ /**
969970 * Attempts to detect the type of a media file based on the URI.
970971 * @param {String} uri URI of the media file.
971972 * @return {String} The guessed MIME type of the file.
@@ -972,14 +973,15 @@
973974 detectType: function( uri ) {
974975 // NOTE: if media is on the same server as the javascript
975976 // we can issue a HEAD request and read the mime type of the media...
976 - // ( this will detect media mime type independently of the url name)
 977+ // ( this will detect media mime type independently of the url name )
977978 // http://www.jibbering.com/2002/4/httprequest.html
978 - var end_inx = ( uri.indexOf( '?' ) != -1 ) ? uri.indexOf( '?' ) : uri.length;
979 - var no_param_uri = uri.substr( 0, end_inx );
980 - switch( no_param_uri.substr( no_param_uri.lastIndexOf( '.' ), 4 ).toLowerCase() ) {
 979+ var urlParts = mw.parseUri( uri );
 980+ // Get the extension from the url or from the relative name:
 981+ var ext = ( urlParts.file )? urlParts.file.substr( -4 ) : uri.substr( -4 );
 982+ switch( ext.toLowerCase() ) {
981983 case 'smil':
982984 case '.sml':
983 - return 'application/smil'
 985+ return 'application/smil';
984986 break;
985987 case '.m4v':
986988 case '.mp4':
@@ -1017,13 +1019,14 @@
10181020 return 'video/mpeg';
10191021 break;
10201022 }
 1023+ mw.log( "Error: could not detect type of media src: " + uri );
10211024 }
10221025 };
10231026
1024 -/**
 1027+/**
10251028 * A media element corresponding to a <video> element.
10261029 *
1027 -* It is implemented as a collection of mediaSource objects. The media sources
 1030+* It is implemented as a collection of mediaSource objects. The media sources
10281031 * will be initialized from the <video> element, its child <source> elements,
10291032 * and/or the ROE file referenced by the <video> element.
10301033 * @param {element} videoElement <video> element used for initialization.
@@ -1034,48 +1037,48 @@
10351038 }
10361039
10371040 mediaElement.prototype = {
1038 -
 1041+
10391042 // The array of mediaSource elements.
10401043 sources: null,
1041 -
 1044+
10421045 // flag for ROE data being added.
10431046 addedROEData: false,
1044 -
1045 - // Selected mediaSource element.
 1047+
 1048+ // Selected mediaSource element.
10461049 selectedSource: null,
1047 -
 1050+
10481051 // Media element thumbnail
10491052 thumbnail: null,
1050 -
1051 - // Media element linkback
 1053+
 1054+ // Media element linkback
10521055 linkback: null,
10531056
10541057 /**
10551058 * Media Element constructor
10561059 *
1057 - * Sets up a mediaElement from a provided top level "video" element
 1060+ * Sets up a mediaElement from a provided top level "video" element
10581061 * adds any child sources that are found
10591062 *
1060 - * @param {Element} videoElement Element that has src attribute or has children source elements
 1063+ * @param {Element} videoElement Element that has src attribute or has children source elements
10611064 */
10621065 init: function( videoElement ) {
1063 - var _this = this;
1064 - mw.log( "EmbedPlayer::mediaElement:init:" + videoElement.id );
1065 - this.sources = new Array();
1066 -
 1066+ var _this = this;
 1067+ mw.log( "EmbedPlayer::mediaElement:init:" + videoElement.id );
 1068+ this.sources = new Array();
 1069+
10671070 // Process the videoElement as a source element:
10681071 if ( $j( videoElement ).attr( "src" ) ) {
10691072 _this.tryAddSource( videoElement );
10701073 }
1071 -
 1074+
10721075 // Process elements source children
1073 - $j( videoElement ).find( 'source,track' ).each( function( ) {
 1076+ $j( videoElement ).find( 'source,track' ).each( function( ) {
10741077 _this.tryAddSource( this );
1075 - } );
 1078+ } );
10761079 },
1077 -
1078 - /**
1079 - * Updates the time request for all sources that have
 1080+
 1081+ /**
 1082+ * Updates the time request for all sources that have
10801083 * a standard time request argument (ie &t=start_time/end_time)
10811084 *
10821085 * @param {String} start_npt Start time in npt format
@@ -1087,26 +1090,26 @@
10881091 mediaSource.updateSrcTime( start_npt, end_npt );
10891092 } );
10901093 },
1091 -
 1094+
10921095 /**
10931096 * Check for Timed Text tracks
10941097 * @return {Boolean} True if text tracks exist, false if no text tracks are found
10951098 */
10961099 textSourceExists: function() {
10971100 for ( var i = 0; i < this.sources.length; i++ ) {
1098 - mw.log('EmbedPlayer::textSourceExists:'+ this.sources[i].mimeType );
1099 - if ( this.sources[i].mimeType == 'text/cmml' ||
1100 - this.sources[i].mimeType == 'text/x-srt' )
 1101+ mw.log('EmbedPlayer::textSourceExists:'+ this.sources[i].mimeType );
 1102+ if ( this.sources[i].mimeType == 'text/cmml' ||
 1103+ this.sources[i].mimeType == 'text/x-srt' )
11011104 {
11021105 return true;
11031106 }
11041107 };
11051108 return false;
11061109 },
1107 -
1108 - /**
 1110+
 1111+ /**
11091112 * Returns the array of mediaSources of this element.
1110 - *
 1113+ *
11111114 * @param {String} [mimeFilter] Filter criteria for set of mediaSources to return
11121115 * @return {Array} mediaSource elements.
11131116 */
@@ -1114,34 +1117,34 @@
11151118 if ( !mimeFilter ) {
11161119 return this.sources;
11171120 }
1118 - // Apply mime filter:
 1121+ // Apply mime filter:
11191122 var source_set = new Array();
11201123 for ( var i = 0; i < this.sources.length ; i++ ) {
11211124 if ( this.sources[i].mimeType &&
1122 - this.sources[i].mimeType.indexOf( mimeFilter ) != -1 )
 1125+ this.sources[i].mimeType.indexOf( mimeFilter ) != -1 )
11231126 {
11241127 source_set.push( this.sources[i] );
11251128 }
11261129 }
11271130 return source_set;
11281131 },
1129 -
 1132+
11301133 /**
11311134 * Selects a source by id
1132 - * @param {String} source_id Id of the source to select.
1133 - * @return {MediaSource} The selected mediaSource or null if not found
 1135+ * @param {String} source_id Id of the source to select.
 1136+ * @return {MediaSource} The selected mediaSource or null if not found
11341137 */
11351138 getSourceById:function( source_id ) {
11361139 for ( var i = 0; i < this.sources.length ; i++ ) {
1137 - if ( this.sources[i].id == source_id ) {
 1140+ if ( this.sources[i].id == source_id ) {
11381141 return this.sources[i];
11391142 }
11401143 }
11411144 return null;
11421145 },
1143 -
1144 - /**
1145 - * Selects a particular source for playback updating the "selectedSource"
 1146+
 1147+ /**
 1148+ * Selects a particular source for playback updating the "selectedSource"
11461149 *
11471150 * @param {Number} index Index of source element to set as selectedSource
11481151 */
@@ -1151,33 +1154,33 @@
11521155 for ( var i = 0; i < playableSources.length; i++ ) {
11531156 if ( i == index ) {
11541157 this.selectedSource = playableSources[i];
1155 - // Update the user selected format:
 1158+ // Update the user selected format:
11561159 mw.EmbedTypes.players.setFormatPreference( playableSources[i].mimeType );
11571160 break;
11581161 }
11591162 }
11601163 },
1161 -
1162 - /**
 1164+
 1165+ /**
11631166 * Selects the default source via cookie preference, default marked, or by id order
11641167 */
1165 - autoSelectSource: function() {
 1168+ autoSelectSource: function() {
11661169 mw.log( 'EmbedPlayer::mediaElement::autoSelectSource:' + this.id);
11671170 // Select the default source
11681171 var playableSources = this.getPlayableSources();
11691172 var flash_flag = ogg_flag = false;
1170 -
 1173+
11711174 // Set via user-preference
11721175 for ( var source = 0; source < playableSources.length; source++ ) {
1173 - var mimeType = playableSources[source].mimeType;
 1176+ var mimeType = playableSources[source].mimeType;
11741177 if ( mw.EmbedTypes.players.preference[ 'format_preference' ] == mimeType ) {
11751178 mw.log( 'Set via preference: ' + playableSources[source].mimeType );
11761179 this.selectedSource = playableSources[source];
11771180 return true;
11781181 }
11791182 }
1180 -
1181 - // Set via marked default:
 1183+
 1184+ // Set via marked default:
11821185 for ( var source = 0; source < playableSources.length; source++ ) {
11831186 if ( playableSources[ source ].markedDefault ) {
11841187 mw.log( 'Set via marked default: ' + playableSources[source].markedDefault );
@@ -1185,37 +1188,37 @@
11861189 return true;
11871190 }
11881191 }
1189 -
1190 - // Prefer native playback
 1192+
 1193+ // Prefer native playback
11911194 for ( var source = 0; source < playableSources.length; source++ ) {
11921195 var mimeType = playableSources[source].mimeType;
1193 - var player = mw.EmbedTypes.players.defaultPlayer( mimeType );
 1196+ var player = mw.EmbedTypes.players.defaultPlayer( mimeType );
11941197 if ( player && player.library == 'Native' ) {
11951198 mw.log('EmbedPlayer::Set native playback');
11961199 this.selectedSource = playableSources[ source ];
11971200 return true;
1198 - }
 1201+ }
11991202 }
1200 -
 1203+
12011204 // Set h264 via native or flash fallback
12021205 for ( var source = 0; source < playableSources.length; source++ ) {
12031206 var mimeType = playableSources[source].mimeType;
1204 - var player = mw.EmbedTypes.players.defaultPlayer( mimeType );
1205 - if ( mimeType == 'video/h264'
1206 - && player
1207 - && (
1208 - player.library == 'Native'
 1207+ var player = mw.EmbedTypes.players.defaultPlayer( mimeType );
 1208+ if ( mimeType == 'video/h264'
 1209+ && player
 1210+ && (
 1211+ player.library == 'Native'
12091212 ||
12101213 player.library == 'Kplayer'
12111214 )
1212 - ) {
 1215+ ) {
12131216 mw.log('Set h264 via native or flash fallback');
12141217 this.selectedSource = playableSources[ source ];
12151218 return true;
12161219 }
12171220 };
1218 -
1219 - // Else just select first source
 1221+
 1222+ // Else just select first source
12201223 if ( !this.selectedSource ) {
12211224 mw.log( 'set via first source:' + playableSources[0] );
12221225 this.selectedSource = playableSources[0];
@@ -1224,30 +1227,30 @@
12251228 // No Source found so no source selected
12261229 return false;
12271230 },
1228 -
 1231+
12291232 /**
1230 - * check if the mime is ogg
1231 - */
 1233+ * check if the mime is ogg
 1234+ */
12321235 isOgg: function( mimeType ){
1233 - if ( mimeType == 'video/ogg'
1234 - || mimeType == 'ogg/video'
1235 - || mimeType == 'video/annodex'
 1236+ if ( mimeType == 'video/ogg'
 1237+ || mimeType == 'ogg/video'
 1238+ || mimeType == 'video/annodex'
12361239 || mimeType == 'application/ogg'
12371240 ) {
12381241 return true;
12391242 }
12401243 return false;
12411244 },
1242 -
1243 - /**
 1245+
 1246+ /**
12441247 * Returns the thumbnail URL for the media element.
12451248 * @returns {String} thumbnail URL
12461249 */
12471250 getPosterSrc: function( ) {
12481251 return this.poster;
12491252 },
1250 -
1251 - /**
 1253+
 1254+ /**
12521255 * Checks whether there is a stream of a specified MIME type.
12531256 * @param {String} mimeType MIME type to check.
12541257 * @return {Boolean} true if sources include MIME false if not.
@@ -1262,31 +1265,31 @@
12631266 }
12641267 return false;
12651268 },
1266 -
 1269+
12671270 /**
12681271 * Checks if media is a playable type
12691272 */
1270 - isPlayableType: function( mimeType ) {
 1273+ isPlayableType: function( mimeType ) {
12711274 if ( mw.EmbedTypes.players.defaultPlayer( mimeType ) ) {
12721275 return true;
12731276 } else {
12741277 return false;
12751278 }
12761279 },
1277 -
1278 - /**
 1280+
 1281+ /**
12791282 * Adds a single mediaSource using the provided element if
1280 - * the element has a 'src' attribute.
 1283+ * the element has a 'src' attribute.
12811284 * @param {Element} element <video>, <source> or <mediaSource> <text> element.
12821285 */
12831286 tryAddSource: function( element ) {
1284 - //mw.log( 'f:tryAddSource:' + $j( element ).attr( "src" ) );
 1287+ mw.log( 'f:tryAddSource:' + $j( element ).attr( "src" ) );
12851288 var newSrc = $j( element ).attr( 'src' );
1286 - if ( newSrc ) {
1287 - // make sure an existing element with the same src does not already exist:
 1289+ if ( newSrc ) {
 1290+ // make sure an existing element with the same src does not already exist:
12881291 for ( var i = 0; i < this.sources.length; i++ ) {
12891292 if ( this.sources[i].src == newSrc ) {
1290 - // Source already exists update any new attr:
 1293+ // Source already exists update any new attr:
12911294 this.sources[i].updateSource( element );
12921295 return this.sources[i];
12931296 }
@@ -1294,19 +1297,19 @@
12951298 }
12961299 // Create a new source
12971300 var source = new mediaSource( element );
1298 -
1299 - this.sources.push( source );
1300 - //mw.log( 'tryAddSource: added source ::' + source + 'sl:' + this.sources.length );
 1301+
 1302+ this.sources.push( source );
 1303+ //mw.log( 'tryAddSource: added source ::' + source + 'sl:' + this.sources.length );
13011304 return source;
13021305 },
1303 -
 1306+
13041307 /**
13051308 * Get playable sources
13061309 *
13071310 * @returns {Array} of playable sources
13081311 */
13091312 getPlayableSources: function() {
1310 - var playableSources = [];
 1313+ var playableSources = [];
13111314 for ( var i = 0; i < this.sources.length; i++ ) {
13121315 if ( this.isPlayableType( this.sources[i].mimeType ) ) {
13131316 playableSources.push( this.sources[i] );
@@ -1316,7 +1319,7 @@
13171320 };
13181321 return playableSources;
13191322 },
1320 -
 1323+
13211324 /**
13221325 * Imports media sources from ROE data.
13231326 * @param roe_data ROE data.
@@ -1324,15 +1327,15 @@
13251328 addROE: function( roe_data ) {
13261329 mw.log( 'EmbedPlayer::mediaElement:addROE' );
13271330 this.addedROEData = true;
1328 - var _this = this;
 1331+ var _this = this;
13291332 if ( roe_data ) {
1330 - var $roeParsed = $j( roe_data.pay_load );
1331 -
 1333+ var $roeParsed = $j( roe_data.pay_load );
 1334+
13321335 // Add media sources:
1333 - $roeParsed.find("mediaSource").each( function( inx, source ) {
 1336+ $roeParsed.find("mediaSource").each( function( inx, source ) {
13341337 _this.tryAddSource( source );
13351338 } );
1336 -
 1339+
13371340 // Set the thumbnail:
13381341 $roeParsed.find( 'img' ).each( function( inx, n ) {
13391342 if ( $j( n ).attr( "id" ) == "stream_thumb" ) {
@@ -1340,7 +1343,7 @@
13411344 _this.poster = $j( n ).attr( "src" );
13421345 }
13431346 } );
1344 -
 1347+
13451348 // Set the linkback:
13461349 $roeParsed.find( 'link' ).each( function( inx, n ) {
13471350 if ( $j( n ).attr( 'id' ) == 'html_linkback' ) {
@@ -1355,10 +1358,10 @@
13561359 };
13571360
13581361
1359 -/**
 1362+/**
13601363 * Base embedPlayer object
13611364 * @param {Element} element, the element used for initialization.
1362 -* @param {Object} customAttributes Attributes for the video interface
 1365+* @param {Object} customAttributes Attributes for the video interface
13631366 * that are not already element attributes
13641367 * @constructor
13651368 */
@@ -1367,69 +1370,69 @@
13681371 };
13691372
13701373 mw.EmbedPlayer.prototype = {
1371 -
 1374+
13721375 // The mediaElement object containing all mediaSource objects
13731376 'mediaElement' : null,
1374 -
 1377+
13751378 // Object that describes the supported feature set of the underling plugin / player
13761379 'supports': { },
1377 -
 1380+
13781381 // Preview mode flag,
1379 - // some plugins don't seek accurately but in preview mode we need
 1382+ // some plugins don't seek accurately but in preview mode we need
13801383 // accurate seeks so we do tricks like hide the image until its ready
13811384 'preview_mode' : false,
1382 -
1383 - // Ready to play
 1385+
 1386+ // Ready to play
13841387 // NOTE: we should switch over to setting the html5 video ready state
1385 - 'readyToPlay' : false,
1386 -
 1388+ 'readyToPlay' : false,
 1389+
13871390 // Stores the loading errors
1388 - 'loadError' : false,
1389 -
 1391+ 'loadError' : false,
 1392+
13901393 // Thumbnail updating flag ( to avoid rewriting an thumbnail thats already being updated)
13911394 'thumbnail_updating' : false,
1392 -
 1395+
13931396 // Thumbnail display flag
13941397 'thumbnail_disp' : true,
1395 -
 1398+
13961399 // Local variable to hold CMML meeta data about the current clip
1397 - // for more on CMML see: http://wiki.xiph.org/CMML
 1400+ // for more on CMML see: http://wiki.xiph.org/CMML
13981401 'cmmlData': null,
1399 -
 1402+
14001403 // Stores the seek time request, Updated by the doSeek function
14011404 'serverSeekTime' : 0,
1402 -
1403 - // If the embedPlayer is current 'seeking'
 1405+
 1406+ // If the embedPlayer is current 'seeking'
14041407 'seeking' : false,
1405 -
1406 - // Percent of the clip buffered:
1407 - 'bufferedPercent' : 0,
1408 -
 1408+
 1409+ // Percent of the clip buffered:
 1410+ 'bufferedPercent' : 0,
 1411+
14091412 // Holds the timer interval function
14101413 'monitorTimerId' : null,
1411 -
 1414+
14121415 // Buffer flags
14131416 'bufferStartFlag' : false,
14141417 'bufferEndFlag' : false,
1415 -
 1418+
14161419 // On done playing
14171420 'donePlayingCount' : 0,
1418 -
 1421+
14191422 /**
1420 - * embedPlayer constructor
 1423+ * embedPlayer constructor
14211424 *
14221425 * @param {Element} element DOM element that we are building the player interface for.
1423 - * @param {Object} customAttributes Attributes supplied via argument (rather than applied to the element)
 1426+ * @param {Object} customAttributes Attributes supplied via argument (rather than applied to the element)
14241427 */
1425 - init: function( element, customAttributes ) {
1426 - var _this = this;
1427 - // Set customAttributes if unset:
 1428+ init: function( element, customAttributes ) {
 1429+ var _this = this;
 1430+ // Set customAttributes if unset:
14281431 if ( !customAttributes ) {
14291432 customAttributes = { };
1430 - }
1431 -
1432 - var playerAttributes = mw.getConfig( 'EmbedPlayer.Attributes' );
1433 - // Setup the player Interface from supported attributes:
 1433+ }
 1434+
 1435+ var playerAttributes = mw.getConfig( 'EmbedPlayer.Attributes' );
 1436+ // Setup the player Interface from supported attributes:
14341437 for ( var attr in playerAttributes ) {
14351438 if ( customAttributes[ attr ] || customAttributes[ attr ] === false ) {
14361439 this[ attr ] = customAttributes[ attr ];
@@ -1446,28 +1449,30 @@
14471450 // string -> boolean
14481451 if( this[ attr ] == "false" ) this[attr] = false;
14491452 if( this[ attr ] == "true" ) this[attr] = true;
1450 - }
1451 -
 1453+ }
 1454+ //
 1455+
 1456+
14521457 if( this.apiTitleKey ){
1453 - this.apiTitleKey = unescape( this.apiTitleKey );
 1458+ this.apiTitleKey = decodeURI( this.apiTitleKey );
14541459 }
1455 -
1456 - // Hide "controls" if using native player controls:
 1460+
 1461+ // Hide "controls" if using native player controls:
14571462 if( this.useNativePlayerControls() ){
14581463 _this.controls = false;
14591464 }
1460 -
 1465+
14611466 // Set the poster:
14621467 if ( $j( element ).attr( 'thumbnail' ) ) {
14631468 _this.poster = $j( element ).attr( 'thumbnail' );
1464 - }
 1469+ }
14651470 if ( $j( element ).attr( 'poster' ) ) {
14661471 _this.poster = $j( element ).attr( 'poster' );
1467 - }
1468 -
1469 - // Set the skin name from the class
 1472+ }
 1473+
 1474+ // Set the skin name from the class
14701475 var sn = $j(element).attr( 'class' );
1471 -
 1476+
14721477 if ( sn && sn != '' ) {
14731478 for ( var n = 0; n < mw.validSkins.length; n++ ) {
14741479 if ( sn.indexOf( mw.validSkins[n].toLowerCase() ) !== -1 ) {
@@ -1475,42 +1480,42 @@
14761481 }
14771482 }
14781483 }
1479 -
1480 - // Set the default skin if unset:
 1484+
 1485+ // Set the default skin if unset:
14811486 if ( !this.skinName ) {
14821487 this.skinName = mw.getConfig( 'EmbedPlayer.SkinName' );
14831488 }
1484 -
 1489+
14851490 if( !this.monitorRate ){
14861491 this.monitorRate = mw.getConfig( 'EmbedPlayer.MonitorRate' );
14871492 }
1488 -
1489 - // Make sure startOffset is cast as an float:
 1493+
 1494+ // Make sure startOffset is cast as an float:
14901495 if ( this.startOffset && this.startOffset.split( ':' ).length >= 2 ) {
14911496 this.startOffset = parseFloat( mw.npt2seconds( this.startOffset ) );
14921497 }
1493 -
1494 - // Make sure offset is in float:
 1498+
 1499+ // Make sure offset is in float:
14951500 this.startOffset = parseFloat( this.startOffset );
1496 -
 1501+
14971502 // Set the source duration ( if provided in the element metaData or durationHint )
14981503 if ( $j( element ).attr( 'duration' ) ) {
14991504 _this.duration = $j( element ).attr( 'duration' );
15001505 }
1501 -
 1506+
15021507 if ( !_this.duration && $j( element ).attr( 'durationHint' ) ) {
15031508 _this.durationHint = $j( element ).attr( 'durationHint' );
15041509 // Convert duration hint if needed:
1505 - _this.duration = mw.npt2seconds( _this.durationHint );
1506 - }
1507 -
1508 - // Make sure duration is a float:
 1510+ _this.duration = mw.npt2seconds( _this.durationHint );
 1511+ }
 1512+
 1513+ // Make sure duration is a float:
15091514 this.duration = parseFloat( this.duration );
1510 - mw.log( 'EmbedPlayer::mediaElement:' + this.id + " duration is: " + this.duration );
1511 -
1512 - // Set the player size attributes based loaded video element:
1513 - this.setPlayerSize( element );
1514 -
 1515+ mw.log( 'EmbedPlayer::mediaElement:' + this.id + " duration is: " + this.duration );
 1516+
 1517+ // Set the player size attributes based loaded video element:
 1518+ this.setPlayerSize( element );
 1519+
15151520 // Set the plugin id
15161521 this.pid = 'pid_' + this.id;
15171522
@@ -1520,17 +1525,17 @@
15211526 //mw.log( 'innerHTML: ' + element.innerHTML );
15221527 this.user_missing_plugin_html = element.innerHTML;
15231528 }
1524 -
1525 - // Add the mediaElement object with the elements sources:
 1529+
 1530+ // Add the mediaElement object with the elements sources:
15261531 this.mediaElement = new mediaElement( element );
1527 -
 1532+
15281533 // Process attribute "sources" for dynamic embedding
15291534 if( customAttributes.sources && customAttributes.sources.length ){
15301535 for( var i =0; i < customAttributes.sources.length ; i ++ ){
1531 - var customSource = customAttributes.sources[i];
 1536+ var customSource = customAttributes.sources[i];
15321537 if( customSource.src ){
15331538 var $source = $j('<source />')
1534 - .attr( 'src', customSource.src );
 1539+ .attr( 'src', customSource.src );
15351540 // xxx todo pull list of valid source attributes from mediaSource prototype
15361541 if( customSource.type ){
15371542 $source.attr('type', customSource.type );
@@ -1543,85 +1548,105 @@
15441549 }
15451550 }
15461551 },
1547 -
 1552+
15481553 /**
1549 - * for plugin-players to update supported features
 1554+ * for plugin-players to update supported features
15501555 */
15511556 updateFeatureSupport: function(){
15521557 return ;
15531558 },
1554 -
 1559+
15551560 /**
15561561 * Set the width & height from css style attribute, element attribute, or by default value
15571562 * if no css or attribute is provided set a callback to resize.
1558 - *
 1563+ *
15591564 * Updates this.width & this.height
1560 - *
1561 - * @param {Element} element Source element to grab size from
 1565+ *
 1566+ * @param {Element} element Source element to grab size from
15621567 */
1563 - setPlayerSize: function( element ) {
1564 -
1565 - this.height = parseInt( $j(element).css( 'height' ) );
1566 - this.width = parseInt( $j(element).css( 'width' ) );
1567 -
1568 - if( !this.height && !this.width ) {
1569 - this.height = parseInt( $j(element).attr( 'height' ) );
1570 - this.width = parseInt( $j(element).attr( 'width' ) );
1571 - }
1572 -
1573 - // Special case for audio
1574 - // Firefox sets audio height to "0px" while webkit uses 32px .. force zero:
1575 - if( element.tagName.toLowerCase() == 'audio' && this.height == '32' ) {
 1568+ setPlayerSize: function( element ) {
 1569+
 1570+ this.height = $j(element).css( 'height' );
 1571+ this.width = $j(element).css( 'width' );
 1572+
 1573+ // Set to parent size ( resize events will cause player size updates)
 1574+ if( this.height.indexOf('100%') != -1 || this.width.indexOf('100%') != -1 ){
 1575+ $relativeParent = $j(element).parents().filter(function() {
 1576+ // reduce to only relative position or "body" elements
 1577+ return $j( this ).is( 'body' ) || $j(this).css( 'position' ) == 'relative';
 1578+ }).slice(0,1); // grab only the "first"
 1579+ this.width = $relativeParent.width();
 1580+ this.height = $relativeParent.height();
 1581+ }
 1582+
 1583+ // Make sure height and width are a number
 1584+ this.height = parseInt( this.height );
 1585+ this.width = parseInt( this.width );
 1586+
 1587+
 1588+
 1589+ // Set via attribute if CSS is zero or NaN and we have an attribute value:
 1590+ this.height = ( ( this.height==0 || isNaN( this.height ) )
 1591+ && $j(element).attr( 'height' ) ) ?
 1592+ parseInt( $j(element).attr( 'height' ) ): this.height;
 1593+ this.width = ( ( this.width == 0 || isNaN( this.width ) )
 1594+ && $j(element).attr( 'width' ) )?
 1595+ parseInt( $j(element).attr( 'width' ) ): this.width;
 1596+
 1597+
 1598+ // Special case for audio
 1599+ // Firefox sets audio height to "0px" while webkit uses 32px .. force zero:
 1600+ if( element.tagName.toLowerCase() == 'audio' && this.height == '32' ) {
15761601 this.height = 0;
1577 - }
1578 -
 1602+ }
 1603+
15791604 // Use default aspect ration to get height or width ( if rewriting a non-audio player )
1580 - if( element.tagName.toLowerCase() != 'audio' && this.videoAspect ) {
1581 - var aspect = this.videoAspect.split( ':' );
1582 - if( this.height && !this.width ) {
 1605+ if( element.tagName.toLowerCase() != 'audio' && this.videoAspect ) {
 1606+ var aspect = this.videoAspect.split( ':' );
 1607+ if( this.height && !this.width ) {
15831608 this.width = parseInt( this.height * ( aspect[0] / aspect[1] ) );
1584 - }
1585 - if( this.width && !this.height ) {
 1609+ }
 1610+ if( this.width && !this.height ) {
15861611 var apectRatio = ( aspect[1] / aspect[0] );
15871612 this.height = parseInt( this.width * ( aspect[1] / aspect[0] ) );
15881613 }
15891614 }
1590 -
1591 - // On load sometimes attr is temporally -1 as we don't have video metadata yet.
 1615+
 1616+ // On load sometimes attr is temporally -1 as we don't have video metadata yet.
15921617 // or in IE we get NaN for width height
1593 - //
1594 - // NOTE: browsers that do support height width should set "waitForMeta" flag in addElement
 1618+ //
 1619+ // NOTE: browsers that do support height width should set "waitForMeta" flag in addElement
15951620 if( ( isNaN( this.height ) && isNaN( this.width ) ) ||
1596 - ( this.height == -1 || this.width == -1 ) ||
 1621+ ( this.height == -1 || this.width == -1 ) ||
15971622 // Check for firefox defaults
1598 - // Note: ideally firefox would not do random guesses at css values
 1623+ // Note: ideally firefox would not do random guesses at css values
15991624 ( (this.height == 150 || this.height == 64 ) && this.width == 300 )
1600 - ) {
 1625+ ) {
16011626 var defaultSize = mw.getConfig( 'EmbedPlayer.DefaultSize' ).split( 'x' );
16021627 this.width = defaultSize[0];
1603 -
1604 - // Special height default for audio tag ( if not set )
 1628+
 1629+ // Special height default for audio tag ( if not set )
16051630 if( element.tagName.toLowerCase() == 'audio' ) {
16061631 this.height = 0;
16071632 }else{
16081633 this.height = defaultSize[1];
16091634 }
1610 - }
1611 -
 1635+ }
16121636 },
16131637 /**
16141638 * Resize the player to a new size
 1639+ * @param {object} size The width height size of the player
16151640 */
16161641 resizePlayer: function( size , animate){
16171642 mw.log("EmbedPlayer::resizePlayer:" + size.width + ' x ' + size.height );
16181643 this.width = size.width;
16191644 this.height = size.height;
16201645 var playerSize = {'width' : this.width, 'height' : this.height };
1621 - // check if height needs to include interface contorls
 1646+ // check if height needs to include interface controls
16221647 if( ! this.controlBuilder.checkOverlayControls() ){
16231648 size.height = size.height + this.controlBuilder.height;
16241649 }
1625 -
 1650+
16261651 if( animate ){
16271652 $j(this).animate(playerSize);
16281653 this.$interface.animate( size );
@@ -1630,68 +1655,68 @@
16311656 this.$interface.css( size );
16321657 }
16331658 },
1634 -
 1659+
16351660 /**
16361661 * Get the player pixel width not including controls
16371662 *
16381663 * @return {Number} pixel height of the video
1639 - */
 1664+ */
16401665 getPlayerWidth: function() {
1641 - return parseInt( this.width );
 1666+ return $j( this ).width();
16421667 },
1643 -
 1668+
16441669 /**
16451670 * Get the player pixel height not including controls
16461671 *
16471672 * @return {Number} pixel height of the video
16481673 */
1649 - getPlayerHeight: function() {
1650 - return parseInt( this.height );
 1674+ getPlayerHeight: function() {
 1675+ return $j( this ).height();
16511676 },
16521677
16531678 /**
1654 - * Check player for sources.
1655 - * If we need to get media sources form an external file
1656 - * that request is issued here
 1679+ * Check player for sources.
 1680+ * If we need to get media sources form an external file
 1681+ * that request is issued here
16571682 */
16581683 checkPlayerSources: function() {
16591684 mw.log( 'EmbedPlayer::checkPlayerSources: ' + this.id );
16601685 var _this = this;
1661 -
1662 - // Scope the end of check for player sources so it can be called in a callback
 1686+
 1687+ // Scope the end of check for player sources so it can be called in a callback
16631688 var finishCheckPlayerSources = function(){
1664 - // Run embedPlayer sources hook
1665 - mw.runTriggersCallback( _this, 'checkPlayerSourcesEvent', function(){
 1689+ // Run embedPlayer sources hook
 1690+ mw.runTriggersCallback( _this, 'checkPlayerSourcesEvent', function(){
16661691 _this.checkForTimedText();
1667 - });
 1692+ });
16681693 };
1669 -
 1694+
16701695 // NOTE: Should could be moved to mediaWiki Api support module
1671 - // only load from api if sources are empty:
 1696+ // only load from api if sources are empty:
16721697 if ( _this.apiTitleKey && this.mediaElement.sources.length == 0) {
16731698 // Load media from external data
1674 - mw.log( 'EmbedPlayer::checkPlayerSources: loading apiTitleKey:' + _this.apiTitleKey );
1675 - _this.loadSourceFromApi( function(){
 1699+ mw.log( 'EmbedPlayer::checkPlayerSources: loading apiTitleKey:' + _this.apiTitleKey );
 1700+ _this.loadSourceFromApi( function(){
16761701 finishCheckPlayerSources();
16771702 } );
16781703 return ;
1679 - } else {
 1704+ } else {
16801705 finishCheckPlayerSources();
16811706 }
16821707 },
1683 -
 1708+
16841709 /**
16851710 * Insert and play a video source ( useful for ads or bumper videos )
1686 - *
 1711+ *
16871712 * Only works while video is in active play back.
1688 - * Only tested with native playback atm.
 1713+ * Only tested with native playback atm.
16891714 */
16901715 insertAndPlaySource: function( source ){
16911716 mw.log("Error: only native playback supports insertAndPlaySource right now");
16921717 },
1693 -
 1718+
16941719 /**
1695 - * Load Source video info from mediaWiki Api title key ( this.apiTitleKey )
 1720+ * Load Source video info from mediaWiki Api title key ( this.apiTitleKey )
16961721 * @@todo move this to mediaWiki 'api' module
16971722 * @param {Function} callback Function called once loading is complete
16981723 */
@@ -1701,16 +1726,16 @@
17021727 mw.log( 'Error no apiTitleKey');
17031728 return false;
17041729 }
1705 -
 1730+
17061731 // Set local apiProvider via config if not defined
17071732 if( !_this.apiProvider ) {
17081733 _this.apiProvider = mw.getConfig( 'EmbedPlayer.ApiProvider' );
1709 - }
1710 -
 1734+ }
 1735+
17111736 // Setup the request
17121737 var request = {
17131738 'prop': 'imageinfo',
1714 - // In case the user added File: or Image: to the apiKey:
 1739+ // In case the user added File: or Image: to the apiKey:
17151740 'titles': 'File:' + this.apiTitleKey.replace( /^(File:|Image:)/ , '' ),
17161741 'iiprop': 'url|size|dimensions|metadata',
17171742 'iiurlwidth': _this.width,
@@ -1727,96 +1752,96 @@
17281753 }
17291754 var page = data.query.pages[i];
17301755 }
1731 - } else {
 1756+ } else {
17321757 callback( false );
17331758 return ;
17341759 }
1735 - // Make sure we have imageinfo:
 1760+ // Make sure we have imageinfo:
17361761 if( ! page.imageinfo || !page.imageinfo[0] ){
17371762 callback( false );
17381763 return ;
17391764 }
17401765 var imageinfo = page.imageinfo[0];
1741 -
 1766+
17421767 // Set the poster
17431768 _this.poster = imageinfo.thumburl;
1744 -
 1769+
17451770 // Add the media src
17461771 _this.mediaElement.tryAddSource(
17471772 $j('<source />')
17481773 .attr( 'src', imageinfo.url )
17491774 .get( 0 )
17501775 );
1751 -
 1776+
17521777 // Set the duration
17531778 if( imageinfo.metadata[2]['name'] == 'length' ) {
17541779 _this.duration = imageinfo.metadata[2]['value'];
17551780 }
1756 -
1757 - // Set the width height
 1781+
 1782+ // Set the width height
17581783 // Make sure we have an accurate aspect ratio
1759 - if( imageinfo.height != 0 && imageinfo.width != 0 ) {
 1784+ if( imageinfo.height != 0 && imageinfo.width != 0 ) {
17601785 _this.height = parseInt( _this.width * ( imageinfo.height / imageinfo.width ) );
17611786 }
1762 -
 1787+
17631788 // Update the css for the player interface
17641789 $j( _this ).css( 'height', _this.height);
1765 -
 1790+
17661791 callback();
17671792 });
17681793 },
1769 -
 1794+
17701795 /**
17711796 * Check if we should load the timedText interface or not.
1772 - *
 1797+ *
17731798 * Note we check for text sources outside of
17741799 */
17751800 isTimedTextSupported: function() {
1776 - // Check for timed text sources or api/ roe url
1777 - if ( ( this.roe || this.apiTitleKey ||
1778 - this.mediaElement.textSourceExists() ) ) {
 1801+ // Check for timed text sources or api/ roe url
 1802+ if ( ( this.roe || this.apiTitleKey ||
 1803+ this.mediaElement.textSourceExists() ) ) {
17791804 return true;
17801805 } else {
17811806 return false;
17821807 }
17831808 },
1784 -
 1809+
17851810 /**
1786 - * Check for timed Text support
 1811+ * Check for timed Text support
17871812 * and load necessary libraries
17881813 */
17891814 checkForTimedText: function( ) {
17901815 var _this = this;
1791 - mw.log( 'EmbedPlayer::checkForTimedText: ' + _this.id + " height: " + this.height );
 1816+ mw.log( 'EmbedPlayer::checkForTimedText: ' + _this.id );
17921817 // Check for timedText support
1793 - if( this.isTimedTextSupported() ) {
 1818+ if( this.isTimedTextSupported() ) {
17941819 mw.load( 'TimedText', function() {
17951820 $j( '#' + _this.id ).timedText();
17961821 _this.setupSourcePlayer();
1797 - });
 1822+ });
17981823 return ;
17991824 }
18001825 _this.setupSourcePlayer();
1801 - },
1802 -
 1826+ },
 1827+
18031828 /**
18041829 * Set up the select source player
18051830 *
1806 - * issues autoSelectSource call
 1831+ * issues autoSelectSource call
18071832 *
1808 - * Sets load error if no source is playable
1809 - */
 1833+ * Sets load error if no source is playable
 1834+ */
18101835 setupSourcePlayer: function() {
18111836 mw.log("EmbedPlayer::setupSourcePlayer: " + this.id );
1812 - // Autoseletct the media source
 1837+ // Autoseletct the media source
18131838 this.mediaElement.autoSelectSource();
1814 -
 1839+
18151840 // Auto select player based on default order
18161841 if ( !this.mediaElement.selectedSource ) {
1817 - // check for parent clip:
 1842+ // check for parent clip:
18181843 if ( typeof this.pc != 'undefined' ) {
1819 - mw.log( 'no sources, type:' + this.type + ' check for html' );
1820 - // do load player if just displaying innerHTML:
 1844+ mw.log( 'no sources, type:' + this.type + ' check for html' );
 1845+ // do load player if just displaying innerHTML:
18211846 if ( this.pc.type == 'text/html' ) {
18221847 this.selectedPlayer = mw.EmbedTypes.players.defaultPlayer( 'text/html' );
18231848 mw.log( 'set selected player:' + this.selectedPlayer.mimeType );
@@ -1825,9 +1850,9 @@
18261851 } else {
18271852 this.selectedPlayer = mw.EmbedTypes.players.defaultPlayer( this.mediaElement.selectedSource.mimeType );
18281853 }
1829 -
 1854+
18301855 if ( this.selectedPlayer ) {
1831 - // Inherit the playback system of the selected player:
 1856+ // Inherit the playback system of the selected player:
18321857 this.inheritEmbedPlayer();
18331858 } else {
18341859 // No source's playable
@@ -1837,31 +1862,31 @@
18381863 missingType += or + this.mediaElement.sources[i].mimeType;
18391864 or = ' or ';
18401865 }
1841 - // Get from parent playlist if set:
 1866+ // Get from parent playlist if set:
18421867 if ( this.pc ){
18431868 missingType = this.pc.type;
18441869 }
1845 -
 1870+
18461871 mw.log( 'No player found for given source type ' + missingType );
18471872 this.showPluginMissingHTML( missingType );
1848 -
1849 - // Call the global player manager to inform this video interface is "ready" for page callback to be proccessed.
 1873+
 1874+ // Call the global player manager to inform this video interface is "ready" for page callback to be proccessed.
18501875 mw.playerManager.playerReady( this );
18511876 }
18521877 },
1853 -
 1878+
18541879 /**
18551880 * Load and inherit methods from the selected player interface
18561881 *
18571882 * @param {Function} callback Function to be called once playback-system has been inherited
18581883 */
18591884 inheritEmbedPlayer: function( callback ) {
1860 - mw.log( "EmbedPlayer::inheritEmbedPlayer:duration is: " + this.getDuration() + ' p: ' + this.id );
1861 -
 1885+ mw.log( "EmbedPlayer::inheritEmbedPlayer:duration is: " + this.getDuration() + ' p: ' + this.id );
 1886+
18621887 // Clear out any non-base embedObj methods:
18631888 if ( this.instanceOf ) {
18641889 eval( 'var tmpObj = mw.EmbedPlayer' + this.instanceOf );
1865 - for ( var i in tmpObj ) { // for in loop oky for object
 1890+ for ( var i in tmpObj ) { // for in loop oky for object
18661891 if ( this[ 'parent_' + i ] ) {
18671892 this[i] = this[ 'parent_' + i];
18681893 } else {
@@ -1869,342 +1894,342 @@
18701895 }
18711896 }
18721897 }
1873 -
 1898+
18741899 // Set up the new embedObj
18751900 mw.log( 'EmbedPlayer::inheritEmbedPlayer: embedding with ' + this.selectedPlayer.library );
18761901 var _this = this;
1877 -
1878 - // Load the selected player
 1902+
 1903+ // Load the selected player
18791904 this.selectedPlayer.load( function() {
18801905 mw.log( 'EmbedPlayer::inheritEmbedPlayer ' + _this.selectedPlayer.library + " player loaded for " + _this.id );
1881 -
 1906+
18821907 // Get embed library player Interface
1883 - var playerInterface = mw[ 'EmbedPlayer' + _this.selectedPlayer.library ];
1884 -
1885 - for ( var method in playerInterface ) {
 1908+ var playerInterface = mw[ 'EmbedPlayer' + _this.selectedPlayer.library ];
 1909+
 1910+ for ( var method in playerInterface ) {
18861911 if ( _this[method] && !_this['parent_' + method] ) {
18871912 _this['parent_' + method] = _this[method];
18881913 }
18891914 _this[ method ] = playerInterface[method];
1890 - }
1891 -
1892 - // Update feature support
 1915+ }
 1916+
 1917+ // Update feature support
18931918 _this.updateFeatureSupport();
1894 -
 1919+
18951920 _this.getDuration();
1896 -
 1921+
18971922 _this.showPlayer();
1898 - // Call the global player manager to inform this video interface is ready:
 1923+ // Call the global player manager to inform this video interface is ready:
18991924 mw.playerManager.playerReady( _this );
1900 -
 1925+
19011926 // Run the callback if provided
19021927 if ( typeof callback == 'function' ){
19031928 callback();
19041929 }
19051930 } );
19061931 },
1907 -
 1932+
19081933 /**
19091934 * Select a player playback system
19101935 *
19111936 * @param {Object} player Player playback system to be selected
1912 - * player playback system include vlc, native, java etc.
 1937+ * player playback system include vlc, native, java etc.
19131938 */
1914 - selectPlayer: function( player ) {
 1939+ selectPlayer: function( player ) {
19151940 var _this = this;
19161941 if ( this.selectedPlayer.id != player.id ) {
19171942 this.selectedPlayer = player;
19181943 this.inheritEmbedPlayer( function(){
19191944 // Hide / remove track container
1920 - _this.$interface.find( '.track' ).remove();
 1945+ _this.$interface.find( '.track' ).remove();
19211946 // We have to re-bind hoverIntent ( has to happen in this scope )
19221947 if( _this.controls && _this.controlBuilder.checkOverlayControls() ){
1923 - _this.controlBuilder.showControlBar();
 1948+ _this.controlBuilder.showControlBar();
19241949 _this.$interface.hoverIntent({
19251950 'sensitivity': 4,
19261951 'timeout' : 2000,
1927 - 'over' : function(){
 1952+ 'over' : function(){
19281953 _this.controlBuilder.showControlBar();
19291954 },
19301955 'out' : function(){
19311956 _this.controlBuilder.hideControlBar();
19321957 }
1933 - })
1934 - }
1935 - });
 1958+ });
 1959+ }
 1960+ });
19361961 }
1937 - },
1938 -
 1962+ },
 1963+
19391964 /**
1940 - * Get a time range from the media start and end time
 1965+ * Get a time range from the media start and end time
19411966 *
19421967 * @return start_npt and end_npt time if present
1943 - */
1944 - getTimeRange: function() {
 1968+ */
 1969+ getTimeRange: function() {
19451970 var end_time = (this.controlBuilder.longTimeDisp)? '/' + mw.seconds2npt( this.getDuration() ) : '';
1946 - var default_time_range = '0:00:00' + end_time;
 1971+ var default_time_range = '0:00:00' + end_time;
19471972 if ( !this.mediaElement )
19481973 return default_time_range;
19491974 if ( !this.mediaElement.selectedSource )
19501975 return default_time_range;
19511976 if ( !this.mediaElement.selectedSource.end_npt )
1952 - return default_time_range;
 1977+ return default_time_range;
19531978 return this.mediaElement.selectedSource.start_npt + this.mediaElement.selectedSource.end_npt;
19541979 },
1955 -
 1980+
19561981 /**
19571982 * Get the duration of the embed player
1958 - */
 1983+ */
19591984 getDuration: function() {
19601985 return this.duration;
1961 - },
1962 -
 1986+ },
 1987+
19631988 /**
19641989 * Get the player height
19651990 */
19661991 getHeight: function() {
19671992 return this.height;
19681993 },
1969 -
 1994+
19701995 /**
19711996 * Get the player width
19721997 */
19731998 getWidth: function(){
19741999 return this.width;
19752000 },
1976 -
 2001+
19772002 /**
1978 - * Check if the selected source is an audio element:
 2003+ * Check if the selected source is an audio element:
19792004 */
19802005 isAudio: function(){
19812006 return ( this.mediaElement.selectedSource.mimeType.indexOf('audio/') !== -1 );
19822007 },
1983 -
 2008+
19842009 /**
19852010 * Get the plugin embed html ( should be implemented by embed player interface )
19862011 */
19872012 doEmbedHTML: function() {
19882013 return 'Error: function doEmbedHTML should be implemented by embed player interface ';
19892014 },
1990 -
 2015+
19912016 /**
19922017 * Seek function ( should be implemented by embedPlayer interface playerNative, playerKplayer etc. )
19932018 * embedPlayer doSeek only handles URL time seeks
1994 - */
 2019+ */
19952020 doSeek: function( percent ) {
19962021 var _this = this;
1997 -
 2022+
19982023 this.seeking = true;
19992024 // Run the seeking hook
20002025 $j( this.embedPlayer ).trigger( 'onSeek' );
2001 -
2002 - // See if we should do a server side seek ( player independent )
2003 - if ( this.supportsURLTimeEncoding() ) {
 2026+
 2027+ // See if we should do a server side seek ( player independent )
 2028+ if ( this.supportsURLTimeEncoding() ) {
20042029 mw.log( 'EmbedPlayer::doSeek:: updated serverSeekTime: ' + mw.seconds2npt ( this.serverSeekTime ) );
20052030 this.stop();
20062031 this.didSeekJump = true;
20072032 // Make sure this.serverSeekTime is up-to-date:
20082033 this.serverSeekTime = mw.npt2seconds( this.start_npt ) + parseFloat( percent * this.getDuration() );
20092034 // Update the slider
2010 - this.updatePlayHead( percent );
2011 - }
2012 -
2013 - // Do play request in 100ms ( give the dom time to swap out the embed player )
2014 - setTimeout( function() {
 2035+ this.updatePlayHead( percent );
 2036+ }
 2037+
 2038+ // Do play request in 100ms ( give the dom time to swap out the embed player )
 2039+ setTimeout( function() {
20152040 _this.seeking = false;
2016 - _this.play()
 2041+ _this.play();
20172042 _this.monitor();
20182043 }, 100 );
2019 -
 2044+
20202045 // Run the onSeeking interface update
2021 - // NOTE controlBuilder should really bind to html5 events rather
2022 - // than explicitly calling it or inheriting stuff.
2023 - this.controlBuilder.onSeek();
2024 - },
2025 -
 2046+ // NOTE controlBuilder should really bind to html5 events rather
 2047+ // than explicitly calling it or inheriting stuff.
 2048+ this.controlBuilder.onSeek();
 2049+ },
 2050+
20262051 /**
2027 - * Seeks to the requested time and issues a callback when ready
 2052+ * Seeks to the requested time and issues a callback when ready
20282053 * (should be overwritten by client that supports frame serving)
20292054 */
20302055 setCurrentTime: function( time, callback ) {
20312056 mw.log( 'Error: base embed setCurrentTime can not frame serve (override via plugin)' );
2032 - },
2033 -
 2057+ },
 2058+
20342059 /**
20352060 * On clip done action. Called once a clip is done playing
20362061 */
20372062 onClipDone: function() {
2038 - mw.log( 'EmbedPlayer::onClipDone:' + this.id + ' doneCount:' + this.donePlayingCount + ' stop state:' +this.isStopped() );
2039 - var _this = this;
2040 -
2041 - // Only run stopped once:
 2063+ mw.log( 'EmbedPlayer::onClipDone:' + this.id + ' doneCount:' + this.donePlayingCount + ' stop state:' +this.isStopped() );
 2064+ var _this = this;
 2065+
 2066+ // Only run stopped once:
20422067 if( !this.isStopped() ){
2043 - // Stop the monitor:
 2068+ // Stop the monitor:
20442069 this.stopMonitor();
2045 -
 2070+
20462071 // Show the control bar:
2047 - this.controlBuilder.showControlBar();
2048 -
 2072+ this.controlBuilder.showControlBar();
 2073+
20492074 // Update the clip done playing count:
20502075 this.donePlayingCount ++;
2051 -
 2076+
20522077 // Fire the html5 ended binding
20532078 var onDoneActionObject = {
20542079 'runBaseControlDone' : true
2055 - }
2056 -
2057 - // Run the ended trigger ( allow the ended object to prevent default actions )
 2080+ };
 2081+
 2082+ // Run the ended trigger ( allow the ended object to prevent default actions )
20582083 mw.log("EmbedPlayer::onClipDone:Trigger ended");
20592084 $j( this ).trigger( 'ended', onDoneActionObject );
2060 -
 2085+
20612086 if( onDoneActionObject.runBaseControlDone ){
2062 -
 2087+
20632088 // Check if we have the "loop" property set
20642089 if( this.loop ) {
20652090 this.stop();
20662091 this.play();
2067 - return;
 2092+ return;
20682093 }
2069 -
2070 - // Stop the clip (load the thumbnail etc)
 2094+
 2095+ // Stop the clip (load the thumbnail etc)
20712096 this.stop();
20722097 this.serverSeekTime = 0;
20732098 this.updatePlayHead( 0 );
2074 -
2075 - // Make sure we are not in preview mode( no end clip actions in preview mode)
 2099+
 2100+ // Make sure we are not in preview mode( no end clip actions in preview mode)
20762101 if ( this.preview_mode ) {
20772102 return ;
2078 - }
2079 -
 2103+ }
 2104+
20802105 // Do the controlBuilder onClip done interface
20812106 this.controlBuilder.onClipDone();
20822107 }
20832108 }
2084 -
20852109 },
2086 -
2087 -
 2110+
 2111+
20882112 /**
20892113 * Shows the video Thumbnail, updates pause state
20902114 */
20912115 showThumbnail: function() {
20922116 var _this = this;
20932117 mw.log( 'EmbedPlayer::showThumbnail' + this.thumbnail_disp );
2094 -
 2118+
20952119 // Close Menu Overlay:
20962120 this.controlBuilder.closeMenuOverlay();
2097 -
2098 - // update the thumbnail html:
 2121+
 2122+ // update the thumbnail html:
20992123 this.updatePosterHTML();
2100 -
 2124+
21012125 this.paused = true;
21022126 this.thumbnail_disp = true;
2103 - // Make sure the controlBuilder bindings are up-to-date
 2127+ // Make sure the controlBuilder bindings are up-to-date
21042128 this.controlBuilder.addControlBindings();
2105 -
 2129+
21062130 // Once the thumbnail is shown run the mediaReady trigger (if not using native controls)
21072131 if( !this.useNativePlayerControls() ){
21082132 mw.log("mediaLoaded");
21092133 $j( this ).trigger( 'mediaLoaded' );
21102134 }
21112135 },
2112 -
 2136+
21132137 /**
21142138 * Show the player
21152139 */
2116 - showPlayer : function () {
2117 - mw.log( 'EmbedPlayer:: Show player: ' + this.id );
 2140+ showPlayer : function () {
 2141+ mw.log( 'EmbedPlayer:: Show player: ' + this.id + ' interace: w:' + this.width + ' h:' + this.height);
21182142 var _this = this;
2119 - // Set-up the local controlBuilder instance:
2120 - this.controlBuilder = new mw.PlayerControlBuilder( this );
 2143+ // Set-up the local controlBuilder instance:
 2144+ this.controlBuilder = new mw.PlayerControlBuilder( this );
21212145 var _this = this;
 2146+
21222147 // Make sure we have mwplayer_interface
21232148 if( $j( this ).parent( '.mwplayer_interface' ).length == 0 ) {
2124 - // Select "player"
2125 - $j( this )
2126 - .wrap(
 2149+ // Select "player"
 2150+ $j( this )
 2151+ .wrap(
21272152 $j('<div>')
21282153 .addClass( 'mwplayer_interface ' + this.controlBuilder.playerClass )
2129 - .css({
2130 - 'width' : parseInt( this.width ) + 'px',
2131 - 'height' : parseInt( this.height ) + 'px',
 2154+ .css({
 2155+ 'width' : this.width + 'px',
 2156+ 'height' : this.height + 'px',
21322157 'position' : 'relative'
21332158 })
2134 - )
 2159+ );
21352160 }
2136 -
2137 - //Set up local jQuery object reference to "mwplayer_interface"
2138 - this.$interface = $j( this ).parent( '.mwplayer_interface' );
2139 -
2140 - // Update Thumbnail for the "player"
2141 - this.updatePosterHTML();
2142 -
 2161+
 2162+ //Set up local jQuery object reference to "mwplayer_interface"
 2163+ this.$interface = $j( this ).parent( '.mwplayer_interface' );
 2164+
 2165+ // Update Thumbnail for the "player"
 2166+ this.updatePosterHTML();
 2167+
21432168 // Add controls if enabled:
2144 - if ( this.controls ) {
 2169+ if ( this.controls ) {
21452170 this.controlBuilder.addControls();
21462171 } else {
2147 - // Need to think about this some more...
2148 - // Interface is hidden if controls are "off"
2149 - this.$interface.hide();
 2172+ // Need to think about this some more...
 2173+ // Interface is hidden if controls are "off"
 2174+ this.$interface.hide();
21502175 }
2151 -
2152 - if ( this.autoplay ) {
 2176+
 2177+ if ( this.autoplay ) {
21532178 mw.log( 'EmbedPlayer::showPlayer::activating autoplay' );
2154 - // Issue a non-blocking play request
 2179+ // Issue a non-blocking play request
21552180 setTimeout(function(){
21562181 _this.play();
2157 - },0)
 2182+ },0);
21582183 }
2159 -
 2184+
21602185 },
2161 -
 2186+
21622187 /**
21632188 * Get missing plugin html (check for user included code)
21642189 * @param {String} [misssingType] missing type mime
21652190 */
21662191 showPluginMissingHTML: function( misssingType ) {
2167 - // Remove the loading spinner if present:
 2192+ // Remove the loading spinner if present:
21682193 $j('.playerLoadingSpinner').remove();
2169 -
2170 - // If the native video is already displayed hide it:
 2194+
 2195+ // If the native video is already displayed hide it:
21712196 if( $j( '#' + this.pid ).length != 0 ){
21722197 $j('#loadingSpinner_' + this.id ).remove();
2173 - $j( '#' + this.pid ).hide()
 2198+ $j( '#' + this.pid ).hide();
21742199 }
21752200 if( this.mediaElement.sources.length == 0 ){
2176 - // hide the pid if present:
 2201+ // Hide the pid if present:
21772202 $j( '#pid_' + this.id ).hide();
21782203 $j( this ).show().html(
2179 - $j('<span />').text(
 2204+ $j('<span />').text(
21802205 gM('mwe-embedplayer-missing-source')
21812206 )
21822207 );
21832208 return ;
21842209 }
2185 - var source = this.mediaElement.sources[0];
2186 - // Check if we have user defined missing html msg:
 2210+ var source = this.mediaElement.sources[0];
 2211+ // Check if we have user defined missing html msg:
21872212 if ( this.user_missing_plugin_html ) {
2188 - $j( this ).html( this.user_missing_plugin_html );
 2213+ $j( this ).html( this.user_missing_plugin_html );
21892214 } else {
2190 - if ( !misssingType ){
2191 - misssingType = '';
2192 - }
2193 - $j( this ).html(
2194 - $j('<div />').append(
2195 - gM( 'mwe-embedplayer-generic_missing_plugin', misssingType ),
2196 - $j( '<br />' ),
2197 - $j( '<a />' )
2198 - .attr( {
2199 - 'title' : gM( 'mwe-embedplayer-download_clip' ),
2200 - 'href' : source.src
2201 - })
2202 - .text( gM( 'mwe-embedplayer-download_clip' ) )
2203 - )
2204 - );
 2215+ if ( !misssingType ){
 2216+ misssingType = '';
 2217+ }
 2218+ $j( this ).html(
 2219+ $j('<div />').append(
 2220+ gM( 'mwe-embedplayer-generic_missing_plugin', misssingType ),
 2221+ $j( '<br />' ),
 2222+ $j( '<a />' )
 2223+ .attr( {
 2224+ 'title' : gM( 'mwe-embedplayer-download_clip' ),
 2225+ 'href' : source.src
 2226+ })
 2227+ .text( gM( 'mwe-embedplayer-download_clip' ) )
 2228+ )
 2229+ );
22052230 }
22062231 // hide
22072232 },
2208 -
 2233+
22092234 /**
22102235 * Update the video time request via a time request string
22112236 * @param {String} time_req
@@ -2214,23 +2239,23 @@
22152240 var time_parts = time_req.split( '/' );
22162241 this.updateVideoTime( time_parts[0], time_parts[1] );
22172242 },
2218 -
2219 - /**
 2243+
 2244+ /**
22202245 * Update Video time from provided start_npt and end_npt values
22212246 *
22222247 * @param {String} start_npt the new start time in npt format
2223 - * @pamra {String} end_npt the new end time in npt format
 2248+ * @pamra {String} end_npt the new end time in npt format
22242249 */
22252250 updateVideoTime: function( start_npt, end_npt ) {
22262251 // update media
22272252 this.mediaElement.updateSourceTimes( start_npt, end_npt );
2228 -
 2253+
22292254 // update mv_time
22302255 this.controlBuilder.setStatus( start_npt + '/' + end_npt );
2231 -
 2256+
22322257 // reset slider
22332258 this.updatePlayHead( 0 );
2234 -
 2259+
22352260 // reset seek_offset:
22362261 if ( this.mediaElement.selectedSource.URLTimeEncoding ) {
22372262 this.serverSeekTime = 0;
@@ -2238,45 +2263,20 @@
22392264 this.serverSeekTime = mw.npt2seconds( start_npt );
22402265 }
22412266 },
2242 -
 2267+
 2268+
22432269 /**
2244 - * Render a thumbnail at a given time
2245 - * NOTE: Should overwrite by embed library if we can render frames natively
2246 - *
2247 - * @param {Object} options Options for rendered timeline thumb
2248 - */
2249 - renderTimelineThumbnail: function( options ) {
2250 - var my_thumb_src = this.mediaElement.getPosterSrc();
2251 - // check if our thumbnail has a time attribute:
2252 - if ( my_thumb_src.indexOf( 't=' ) !== -1 ) {
2253 - var time_ntp = mw.seconds2npt ( options.time + parseInt( this.startOffset ) );
2254 - my_thumb_src = mw.replaceUrlParams( my_thumb_src, {
2255 - 't' : time_ntp,
2256 - 'size' : options.size
2257 - });
2258 - }
2259 - var thumb_class = ( typeof options['thumb_class'] != 'undefined' ) ? options['thumb_class'] : '';
2260 - return '<div class="ui-corner-all ' + thumb_class + '" src="' + my_thumb_src + '" ' +
2261 - 'style="height:' + options.height + 'px;' +
2262 - 'width:' + options.width + 'px" >' +
2263 - '<img src="' + my_thumb_src + '" ' +
2264 - 'style="height:' + options.height + 'px;' +
2265 - 'width:' + options.width + 'px">' +
2266 - '</div>';
2267 - },
2268 -
2269 - /**
22702270 * Update Thumb time with npt formated time
22712271 * @param {String} time NPT formated time to update thumbnail
2272 - */
 2272+ */
22732273 updateThumbTimeNPT: function( time ) {
22742274 this.updateThumbTime( mw.npt2seconds( time ) - parseInt( this.startOffset ) );
22752275 },
2276 -
 2276+
22772277 /**
2278 - * Update the thumb with a new time
 2278+ * Update the thumb with a new time
22792279 * @param {Float} floatSeconds Time to update the thumb to
2280 - */
 2280+ */
22812281 updateThumbTime:function( floatSeconds ) {
22822282 // mw.log('updateThumbTime:'+floatSeconds);
22832283 var _this = this;
@@ -2285,8 +2285,8 @@
22862286 }
22872287 if ( this.org_thum_src.indexOf( 't=' ) !== -1 ) {
22882288 this.last_thumb_url = mw.replaceUrlParams( this.org_thum_src,
2289 - {
2290 - 't' : mw.seconds2npt( floatSeconds + parseInt( this.startOffset ) )
 2289+ {
 2290+ 't' : mw.seconds2npt( floatSeconds + parseInt( this.startOffset ) )
22912291 }
22922292 );
22932293 if ( !this.thumbnail_updating ) {
@@ -2295,33 +2295,33 @@
22962296 }
22972297 }
22982298 },
2299 -
2300 - /**
 2299+
 2300+ /**
23012301 * Updates the displayed thumbnail via percent of the stream
23022302 * @param {Float} percent Percent of duration to update thumb
23032303 */
23042304 updateThumbPerc:function( percent ) {
23052305 return this.updateThumbTime( ( this.getDuration() * percent ) );
23062306 },
2307 -
 2307+
23082308 /**
23092309 * Updates the thumbnail if the thumbnail is being displayed
2310 - *
 2310+ *
23112311 * @param {String} src New src of thumbnail
2312 - * @param {Boolean} quick_switch
 2312+ * @param {Boolean} quick_switch
23132313 * true switch happens instantly
23142314 * false / undefined animated cross fade
23152315 */
23162316 updatePosterSrc: function( src, quick_switch ) {
2317 - // make sure we don't go to the same url if we are not already updating:
 2317+ // make sure we don't go to the same url if we are not already updating:
23182318 if ( !this.thumbnail_updating && $j( '#img_thumb_' + this.id ).attr( 'src' ) == src )
23192319 return false;
2320 - // if we are already updating don't issue a new update:
 2320+ // if we are already updating don't issue a new update:
23212321 if ( this.thumbnail_updating && $j( '#new_img_thumb_' + this.id ).attr( 'src' ) == src )
23222322 return false;
2323 -
 2323+
23242324 mw.log( 'update thumb: ' + src );
2325 -
 2325+
23262326 if ( quick_switch ) {
23272327 $j( '#img_thumb_' + this.id ).attr( 'src', src );
23282328 } else {
@@ -2329,11 +2329,11 @@
23302330 // if still animating remove new_img_thumb_
23312331 if ( this.thumbnail_updating == true )
23322332 $j( '#new_img_thumb_' + this.id ).stop().remove();
2333 -
 2333+
23342334 if ( this.thumbnail_disp ) {
23352335 mw.log( 'set to thumb:' + src );
23362336 this.thumbnail_updating = true;
2337 - $j( this ).append(
 2337+ $j( this ).append(
23382338 $j('<img />')
23392339 .attr({
23402340 'src' : src,
@@ -2344,17 +2344,17 @@
23452345 .css( {
23462346 'display' : 'none',
23472347 'position' : 'absolute',
2348 - 'zindex' : 2,
 2348+ 'z-index' : 2,
23492349 'top' : '0px',
23502350 'left' : '0px'
23512351 })
23522352 );
2353 - // mw.log('appended: new_img_thumb_');
 2353+ // mw.log('appended: new_img_thumb_');
23542354 $j( '#new_img_thumb_' + this.id ).fadeIn( "slow", function() {
23552355 // once faded in remove org and rename new:
23562356 $j( '#img_thumb_' + _this.id ).remove();
23572357 $j( '#new_img_thumb_' + _this.id ).attr( 'id', 'img_thumb_' + _this.id );
2358 - $j( '#img_thumb_' + _this.id ).css( 'zindex', '1' );
 2358+ $j( '#img_thumb_' + _this.id ).css( 'z-index', '1' );
23592359 _this.thumbnail_updating = false;
23602360 // mw.log("done fadding in "+ $j('#img_thumb_'+_this.id).attr("src"));
23612361
@@ -2368,8 +2368,8 @@
23692369 }
23702370 }
23712371 },
2372 -
2373 - /**
 2372+
 2373+ /**
23742374 * Returns the HTML code for the video when it is in thumbnail mode.
23752375 * playing, configuring the player, inline cmml display, HTML linkback,
23762376 * download, and embed code.
@@ -2379,23 +2379,23 @@
23802380 var thumb_html = '';
23812381 var class_atr = '';
23822382 var style_atr = '';
2383 -
2384 -
 2383+
 2384+
23852385 if( this.useNativePlayerControls() ){
23862386 this.showNativePlayer();
23872387 return ;
2388 - }
2389 -
 2388+ }
 2389+
23902390 // Set by default thumb value if not found
2391 - var posterSrc = ( this.poster ) ? this.poster :
2392 - mw.getConfig( 'imagesPath' ) + 'vid_default_thumb.jpg';
2393 -
 2391+ var posterSrc = ( this.poster ) ? this.poster :
 2392+ mw.getConfig( 'imagesPath' ) + 'vid_default_thumb.jpg';
 2393+
23942394 // Poster support is not very consistent in browsers
2395 - // use a jpeg poster image:
 2395+ // use a jpeg poster image:
23962396 $j( this ).html(
23972397 $j( '<img />' )
23982398 .css({
2399 - 'position' : 'relative',
 2399+ 'position' : 'relative',
24002400 'width' : '100%',
24012401 'height' : '100%'
24022402 })
@@ -2405,28 +2405,28 @@
24062406 })
24072407 .addClass( 'playerPoster' )
24082408 );
2409 -
2410 - if ( this.controls
2411 - && this.height > this.controlBuilder.getComponentHeight( 'playButtonLarge' )
 2409+
 2410+ if ( this.controls
 2411+ && this.height > this.controlBuilder.getComponentHeight( 'playButtonLarge' )
24122412 ) {
24132413 $j( this ).append(
24142414 this.controlBuilder.getComponent( 'playButtonLarge' )
24152415 );
2416 - }
 2416+ }
24172417 },
2418 -
 2418+
24192419 /**
2420 - * Checks if native controls should be used
 2420+ * Checks if native controls should be used
24212421 *
2422 - * @param [player] Object Optional player object to check controls attribute
 2422+ * @param [player] Object Optional player object to check controls attribute
24232423 * @returns boolean true if the mwEmbed player interface should be used
24242424 * false if the mwEmbed player interface should not be used
24252425 */
2426 - useNativePlayerControls: function() {
 2426+ useNativePlayerControls: function() {
24272427 if( this.usenativecontrols === true ){
24282428 return true;
24292429 }
2430 -
 2430+
24312431 if( mw.getConfig('EmbedPlayer.NativeControls') === true ) {
24322432 return true;
24332433 }
@@ -2434,30 +2434,30 @@
24352435 mw.isMobileHTML5()
24362436 ){
24372437 return true;
2438 - }
 2438+ }
24392439 return false;
24402440 },
2441 -
2442 -
 2441+
 2442+
24432443 /**
2444 - * Show the native player embed code
 2444+ * Show the native player embed code
24452445 *
2446 - * This is for cases where the main library needs to "get out of the way"
2447 - * since the device only supports a limited subset of the html5 and
 2446+ * This is for cases where the main library needs to "get out of the way"
 2447+ * since the device only supports a limited subset of the html5 and
24482448 * won't work with an html javascirpt interface
24492449 */
24502450 showNativePlayer: function(){
24512451 var _this = this;
24522452 // Empty the player
24532453 $j(this).empty();
2454 -
 2454+
24552455 // Remove the player loader spinner if it exists
24562456 $j('#loadingSpinner_' + this.id ).remove();
2457 -
2458 -
 2457+
 2458+
24592459 // Check if we need to refresh mobile safari
2460 - var mobileSafariNeedsRefresh = false;
2461 -
 2460+ var mobileSafariNeedsRefresh = false;
 2461+
24622462 // Unhide the original video element if not part of a playerThemer embed
24632463 if( !$j( '#' + this.pid ).hasClass('PlayerThemer') ){
24642464 $j( '#' + this.pid )
@@ -2466,27 +2466,27 @@
24672467 } )
24682468 .show()
24692469 .attr('controls', 'true');
2470 -
 2470+
24712471 mobileSafariNeedsRefresh = true;
24722472 }
2473 -
2474 - // iPad does not handle video tag update for attributes like "controls"
2475 - // so we have to do a full replace ( if controls are not included initially )
 2473+
 2474+ // iPad does not handle video tag update for attributes like "controls"
 2475+ // so we have to do a full replace ( if controls are not included initially )
24762476 if( mw.isMobileHTML5() && mobileSafariNeedsRefresh ) {
24772477 var source = this.mediaElement.getSources( 'video/h264' )[0];
2478 - // XXX note this should be updated once mobile supports h.264
 2478+ // XXX note this should be updated once mobile supports h.264
24792479 if( !source || !source.src ){
24802480 mw.log( 'Warning: Your probably fakeing the iPhone userAgent ( no h.264 source )' );
24812481 source = this.mediaElement.getSources( 'video/ogg' )[0];
24822482 }
2483 -
 2483+
24842484 var videoAttribues = {
24852485 'id' : _this.pid,
24862486 'poster': _this.poster,
24872487 'src' : source.src,
24882488 'controls' : 'true'
2489 - }
2490 -
 2489+ };
 2490+
24912491 if( this.loop ){
24922492 videoAttribues[ 'loop' ] = 'true';
24932493 }
@@ -2494,9 +2494,9 @@
24952495 'width' : _this.width,
24962496 'height' : _this.height
24972497 };
2498 - $j( '#' + this.pid ).replaceWith(
2499 - _this.getNativePlayerHtml( videoAttribues, cssStyle )
2500 - )
 2498+ $j( '#' + this.pid ).replaceWith(
 2499+ _this.getNativePlayerHtml( videoAttribues, cssStyle )
 2500+ );
25012501 // Bind native events:
25022502 this.applyMediaElementBindings();
25032503 }
@@ -2504,14 +2504,14 @@
25052505 // and only with 'native display'
25062506 if( mw.isAndroid2() ){
25072507 $j( '#' + _this.pid ).siblings('.play-btn-large').remove();
2508 - $j( '#' + _this.pid ).after(
2509 - $j('<div />')
 2508+ $j( '#' + _this.pid ).after(
 2509+ $j('<div />')
25102510 .css({
25112511 'position' : 'relative',
25122512 'top' : -1 * ( .5 * _this.getPlayerHeight() ) - 52,
25132513 'left' : ( .5 * _this.getPlayerWidth() ) - 75
25142514 })
2515 - .attr( {
 2515+ .attr( {
25162516 'title' : gM( 'mwe-embedplayer-play_clip' ),
25172517 'class' : "ui-state-default play-btn-large"
25182518 } )
@@ -2519,12 +2519,12 @@
25202520 _this.play();
25212521 // no need to hide the play button since android plays fullscreen
25222522 } )
2523 - )
2524 - }
 2523+ );
 2524+ }
25252525 return ;
25262526 },
25272527 /**
2528 - * Should be set via native embed support
 2528+ * Should be set via native embed support
25292529 */
25302530 getNativePlayerHtml: function(){
25312531 return $j('<div />' )
@@ -2532,168 +2532,160 @@
25332533 .html( 'Error: Trying to get native html5 player without native support for codec' );
25342534 },
25352535 /**
2536 - * Should be set via native embed support
 2536+ * Should be set via native embed support
25372537 */
25382538 applyMediaElementBindings: function(){
25392539 return ;
25402540 },
2541 -
 2541+
25422542 /**
25432543 * Gets code to embed the player remotely for "share" this player links
2544 - */
 2544+ */
25452545 getEmbeddingHTML: function() {
25462546 switch( mw.getConfig( 'EmbedPlayer.ShareEmbedMode' ) ){
2547 - case 'object':
2548 - return this.getShareEmbedObject()
 2547+ case 'iframe':
 2548+ return this.getShareIframeObject();
25492549 break;
25502550 case 'videojs':
25512551 return this.getShareEmbedVideoJs();
25522552 break;
25532553 }
25542554 },
2555 -
 2555+
25562556 /**
25572557 * Get the share embed object code
2558 - *
 2558+ *
25592559 * NOTE this could probably share a bit more code with getShareEmbedVideoJs
2560 - */
2561 - getShareEmbedObject: function(){
 2560+ */
 2561+ getShareIframeObject: function(){
25622562 var iframeUrl = mw.getMwEmbedPath() + 'mwEmbedFrame.php?';
2563 -
 2563+ var params = {};
 2564+
25642565 if ( this.roe ) {
2565 - iframeUrl += 'roe=' + escape( this.roe ) + '&';
2566 - } else if( this.apiTitleKey ) {
2567 - iframeUrl += 'apiTitleKey=' + escape( this.apiTitleKey ) + '&';
 2566+ params.roe = this.roe;
 2567+ } else if( this.apiTitleKey ) {
 2568+ params.apiTitleKey = this.apiTitleKey;
25682569 if ( this.apiProvider ) {
2569 - // Commons always uses the commons api provider ( special hack should refactor )
 2570+ // Commons always uses the commons api provider ( special hack should refactor )
25702571 if( mw.parseUri( document.URL ).host == 'commons.wikimedia.org'){
25712572 this.apiProvider = 'commons';
25722573 }
2573 - iframeUrl += 'apiProvider=' + escape( this.apiProvider ) + '&';
 2574+ params.apiProvider = this.apiProvider;
25742575 }
2575 - } else {
 2576+ } else {
25762577 // Output all the video sources:
25772578 for( var i=0; i < this.mediaElement.sources.length; i++ ){
25782579 var source = this.mediaElement.sources[i];
25792580 if( source.src ) {
2580 - iframeUrl += 'src[]=' + escape( mw.absoluteUrl( source.src ) ) + '&';
 2581+ params['src[]'] = mw.absoluteUrl( source.src );
25812582 }
25822583 }
25832584 // Output the poster attr
25842585 if( this.poster ){
2585 - iframeUrl += 'poster=' + escape( this.poster ) + '&';
 2586+ params.poster = this.poster;
25862587 }
25872588 }
2588 -
 2589+
25892590 // Set the skin if set to something other than default
25902591 if( this.skinName ){
2591 - iframeUrl += 'skin=' + escape( this.skinName ) + '&';
 2592+ params.skin = this.skinName;
25922593 }
2593 -
 2594+
25942595 if( this.duration ) {
2595 - iframeUrl +='durationHint=' + escape( parseFloat( this.duration ) ) + '&';
 2596+ params.durationHint = parseFloat( this.duration );
25962597 }
2597 - // Set width / height of iframe embed ( child iframe / object can't read parent frame size )
2598 - if( this.width || this.height ){
2599 - iframeUrl += ( this.width )? 'width=' + parseInt( this.width ) + '&' : '';
2600 - iframeUrl += ( this.height )? 'height=' +parseInt( this.height ) + '&' : '';
2601 - }
2602 -
 2598+ iframeUrl += $j.param( params );
 2599+
26032600 // Set up embedFrame src path
2604 - var embedCode = '&lt;object data=&quot;' + mw.escapeQuotesHTML( iframeUrl ) + '&quot; ';
2605 -
2606 - // Set width / height of embed object ( give extra space for controls )
2607 - if( this.width || this.height ){
2608 - embedCode += ( this.width )? 'width=&quot;' + this.width +'&quot; ': '';
2609 - embedCode += ( this.height )? 'height=&quot;' +
2610 - parseInt( this.height + this.controlBuilder.getHeight() + 2 ) +
2611 - '&quot; ': '';
2612 - }
2613 - //Make sure overflow is hidden:
2614 - embedCode += 'style=&quot;overflow:hidden&quot; ';
2615 -
2616 - // Close up the embedCode tag:
2617 - embedCode+='&gt;&lt/object&gt;';
2618 -
 2601+ var embedCode = '&lt;iframe src=&quot;' + mw.escapeQuotesHTML( iframeUrl ) + '&quot; ';
 2602+
 2603+ // Set width / height of embed object
 2604+ embedCode += 'width=&quot;' + this.getPlayerWidth() +'&quot; ';
 2605+ embedCode += 'height=&quot;' + this.getPlayerHeight() + '&quot; ';
 2606+ embedCode += 'frameborder=&quot;0&quot; ';
 2607+
 2608+ // Close up the embedCode tag:
 2609+ embedCode+='&gt;&lt/iframe&gt;';
 2610+
26192611 // Return the embed code
26202612 return embedCode;
26212613 },
2622 -
 2614+
26232615 /**
26242616 * Get the share embed Video tag code
2625 - */
 2617+ */
26262618 getShareEmbedVideoJs: function(){
2627 -
2628 - // Set the embed tag type:
 2619+
 2620+ // Set the embed tag type:
26292621 var embedtag = ( this.isAudio() )? 'audio': 'video';
2630 -
2631 - // Set up the mwEmbed js include:
 2622+
 2623+ // Set up the mwEmbed js include:
26322624 var embedCode = '&lt;script type=&quot;text/javascript&quot; ' +
2633 - 'src=&quot;' +
2634 - mw.escapeQuotesHTML(
2635 - mw.absoluteUrl(
2636 - mw.getMwEmbedSrc()
 2625+ 'src=&quot;' +
 2626+ mw.escapeQuotesHTML(
 2627+ mw.absoluteUrl(
 2628+ mw.getMwEmbedSrc()
26372629 )
26382630 ) + '&quot;&gt;&lt;/script&gt' +
26392631 '&lt;' + embedtag + ' ';
26402632
26412633 if( this.poster ) {
26422634 embedCode += 'poster=&quot;' +
2643 - mw.escapeQuotesHTML( mw.absoluteUrl( this.poster ) ) +
 2635+ mw.escapeQuotesHTML( mw.absoluteUrl( this.poster ) ) +
26442636 '&quot; ';
26452637 }
2646 -
 2638+
26472639 // Set the skin if set to something other than default
26482640 if( this.skinName ){
26492641 embedCode += 'class=&quot;' +
2650 - mw.escapeQuotesHTML( this.skinName ) +
 2642+ mw.escapeQuotesHTML( this.skinName ) +
26512643 '&quot; ';
26522644 }
2653 -
 2645+
26542646 if( this.duration ) {
26552647 embedCode +='durationHint=&quot;' + parseFloat( this.duration ) + '&quot; ';
26562648 }
2657 -
 2649+
26582650 if( this.width || this.height ){
26592651 embedCode +='style=&quot;';
26602652 embedCode += ( this.width )? 'width:' + this.width +'px;': '';
26612653 embedCode += ( this.height )? 'height:' + this.height +'px;': '';
26622654 embedCode += '&quot; ';
26632655 }
2664 -
2665 -
 2656+
 2657+
26662658 if ( this.roe ) {
26672659 embedCode += 'roe=&quot;' + mw.escapeQuotesHTML( this.roe ) + '&quot; ';
2668 - } else if( this.apiTitleKey ) {
 2660+ } else if( this.apiTitleKey ) {
26692661 embedCode += 'apiTitleKey=&quot;' + mw.escapeQuotesHTML( this.apiTitleKey ) + '&quot; ';
26702662 if ( this.apiProvider ) {
26712663 embedCode += 'apiProvider=&quot;' + mw.escapeQuotesHTML( this.apiProvider ) + '&quot; ';
26722664 }
26732665 // close the video tag
26742666 embedCode += '&gt;&lt;/video&gt;';
2675 -
 2667+
26762668 } else {
26772669 //Close the video attr
26782670 embedCode += '&gt;';
2679 -
 2671+
26802672 // Output all the video sources:
26812673 for( var i=0; i < this.mediaElement.sources.length; i++ ){
26822674 var source = this.mediaElement.sources[i];
26832675 if( source.src ) {
2684 - embedCode +='&lt;source src=&quot;' +
2685 - mw.absoluteUrl( source.src ) +
 2676+ embedCode +='&lt;source src=&quot;' +
 2677+ mw.absoluteUrl( source.src ) +
26862678 '&quot; &lt;&gt;/source&gt;';
26872679 }
2688 - }
 2680+ }
26892681 // Close the video tag
2690 - embedCode += '&lt;/video&gt;';
2691 - }
2692 -
 2682+ embedCode += '&lt;/video&gt;';
 2683+ }
 2684+
26932685 return embedCode;
26942686 },
2695 -
 2687+
26962688 /**
2697 - * Follows a linkback. Loads the ROE xml if no linkback is found
 2689+ * Follows a linkback. Loads the ROE xml if no linkback is found
26982690 */
26992691 doLinkBack: function() {
27002692 if ( ! this.linkback && this.roe && this.mediaElement.addedROEData == false ) {
@@ -2712,12 +2704,12 @@
27132705 this.displayMenuOverlay( gM( 'mwe-embedplayer-could_not_find_linkback' ) );
27142706 }
27152707 }
2716 - },
2717 -
 2708+ },
 2709+
27182710 /**
27192711 * Base Embed Controls
27202712 */
2721 -
 2713+
27222714 /**
27232715 * The Play Action
27242716 *
@@ -2725,60 +2717,61 @@
27262718 * seeking =false
27272719 * paused = false
27282720 * Updates pause button
2729 - * Starts the "monitor"
 2721+ * Starts the "monitor"
27302722 */
27312723 play: function() {
2732 - var _this = this;
2733 - mw.log( "EmbedPlayer:: play" );
 2724+ var _this = this;
 2725+ // Run play hook (if we we did not bind the native player )
 2726+ if( this.paused && this.useNativePlayerControls() ){
 2727+ this.paused = false;
 2728+ mw.log("trigger play event::" + !this.paused);
 2729+ $j( this ).trigger( 'play' );
 2730+ }
 2731+ this.paused = false;
 2732+
 2733+ mw.log( "EmbedPlayer:: play" );
27342734 // Hide any overlay:
27352735 this.controlBuilder.closeMenuOverlay();
2736 -
 2736+
27372737 // Check if thumbnail is being displayed and embed html
27382738 if ( this.thumbnail_disp ) {
27392739 if ( !this.selectedPlayer ) {
2740 - mw.log( 'no selectedPlayer' );
 2740+ mw.log( 'no selectedPlayer' );
27412741 this.showPluginMissingHTML();
2742 - return;
 2742+ return;
27432743 } else {
27442744 this.thumbnail_disp = false;
2745 - this.doEmbedHTML();
 2745+ this.doEmbedHTML();
27462746 }
27472747 } else {
2748 - // the plugin is already being displayed
 2748+ // the plugin is already being displayed
27492749 this.seeking = false;
27502750 }
2751 -
2752 - // Run play hook (if we were previously in paused state )
2753 - if( this.paused ){
2754 - this.paused = false;
2755 - mw.log("trigger play event::");
2756 - $j( this ).trigger( 'play' );
2757 - }
2758 -
2759 -
 2751+
 2752+
27602753 this.$interface.find('.play-btn span')
27612754 .removeClass( 'ui-icon-play' )
27622755 .addClass( 'ui-icon-pause' );
2763 -
 2756+
27642757 this.$interface.find( '.play-btn' )
2765 - .unbind()
 2758+ .unbind()
27662759 .buttonHover()
27672760 .click( function( ) {
27682761 _this.pause();
2769 - } )
2770 - .attr( 'title', gM( 'mwe-embedplayer-pause_clip' ) );
 2762+ } )
 2763+ .attr( 'title', gM( 'mwe-embedplayer-pause_clip' ) );
27712764
27722765 // Start the monitor if not already started
27732766 this.monitor();
2774 -
2775 - // If we previously finished playing this clip run the "replay hook"
2776 - if( this.donePlayingCount > 0 ) {
2777 - mw.log("replayEvent");
2778 - $j( this ).trigger( 'replayEvent' );
2779 - }
 2767+
 2768+ // If we previously finished playing this clip run the "replay hook"
 2769+ if( this.donePlayingCount > 0 ) {
 2770+ mw.log("replayEvent");
 2771+ $j( this ).trigger( 'replayEvent' );
 2772+ }
27802773 },
2781 -
2782 -
 2774+
 2775+
27832776 /**
27842777 * Maps the html5 load request. There is no general way to "load" clips so
27852778 * underling plugin-player libs should override.
@@ -2786,8 +2779,8 @@
27872780 load: function() {
27882781 // should be done by child (no base way to pre-buffer video)
27892782 mw.log( 'baseEmbed:load call' );
2790 - },
2791 -
 2783+ },
 2784+
27922785 /**
27932786 * Base embed pause
27942787 * Updates the play/pause button state.
@@ -2797,32 +2790,32 @@
27982791 */
27992792 pause: function( event ) {
28002793 var _this = this;
2801 -
2802 - // only trigger the pause event if not already in paused state:
2803 - if( this.paused === false ){
 2794+ // Trigger the pause event if not already paused and using native controls:
 2795+ if( this.paused === false && this.useNativePlayerControls() ){
28042796 this.paused = true;
2805 - mw.log('EmbedPlayer:trigger pause');
2806 - //$j( this ).trigger('pause' );
2807 - }
2808 -
2809 - // update the ctrl "paused state"
 2797+ mw.log('EmbedPlayer:trigger pause:' + this.paused);
 2798+ $j( this ).trigger('pause' );
 2799+ }
 2800+ this.paused = true;
 2801+
 2802+ // update the ctrl "paused state"
28102803 this.$interface.find('.play-btn span' )
28112804 .removeClass( 'ui-icon-pause' )
28122805 .addClass( 'ui-icon-play' );
2813 -
 2806+
28142807 this.$interface.find('.play-btn' )
28152808 .unbind()
28162809 .buttonHover()
28172810 .click( function() {
28182811 _this.play();
28192812 } )
2820 - .attr( 'title', gM( 'mwe-embedplayer-play_clip' ) );
 2813+ .attr( 'title', gM( 'mwe-embedplayer-play_clip' ) );
28212814 },
2822 -
 2815+
28232816 /**
2824 - * Base embed stop
2825 - *
2826 - * Updates the player to the stop state
 2817+ * Base embed stop
 2818+ *
 2819+ * Updates the player to the stop state
28272820 * shows Thumbnail
28282821 * resets Buffer
28292822 * resets Playhead slider
@@ -2830,15 +2823,15 @@
28312824 */
28322825 stop: function() {
28332826 var _this = this;
2834 - mw.log( 'EmbedPlayer::stop:' + this.id );
2835 -
 2827+ mw.log( 'EmbedPlayer::stop:' + this.id );
 2828+
28362829 // no longer seeking:
28372830 this.didSeekJump = false;
2838 -
 2831+
28392832 // Reset current time and prev time and seek offset
2840 - this.currentTime = this.previousTime = this.serverSeekTime = 0;
2841 -
2842 - // Issue pause to update interface (only call this parent)
 2833+ this.currentTime = this.previousTime = this.serverSeekTime = 0;
 2834+
 2835+ // Issue pause to update interface (only call this parent)
28432836 if( !this.paused ){
28442837 this.paused = true;
28452838 // update the interface
@@ -2847,46 +2840,46 @@
28482841 } else {
28492842 this.pause();
28502843 }
2851 - }
2852 -
 2844+ }
 2845+
28532846 // Rewrite the html to thumbnail disp
28542847 this.showThumbnail();
2855 - this.bufferedPercent = 0; // reset buffer state
 2848+ this.bufferedPercent = 0; // reset buffer state
28562849 this.controlBuilder.setStatus( this.getTimeRange() );
2857 -
 2850+
28582851 // Reset the playhead
2859 - mw.log("EmbedPlayer::Stop:: Reset play head")
 2852+ mw.log("EmbedPlayer::Stop:: Reset play head");
28602853 this.updatePlayHead( 0 );
2861 -
2862 - //Bind play-btn-large play
 2854+
 2855+ //Bind play-btn-large play
28632856 this.$interface.find( '.play-btn-large' )
28642857 .unbind( 'click' )
28652858 .click( function() {
28662859 _this.play();
2867 - } );
 2860+ } );
28682861 },
2869 -
 2862+
28702863 /**
28712864 * Base Embed mute
2872 - *
 2865+ *
28732866 * Handles interface updates for toggling mute.
28742867 * Plug-in / player interface must handle the actual media player update
28752868 */
28762869 toggleMute: function() {
2877 - mw.log( 'f:toggleMute:: (old state:) ' + this.muted );
 2870+ mw.log( 'f:toggleMute:: (old state:) ' + this.muted );
28782871 if ( this.muted ) {
2879 - this.muted = false;
2880 - var percent = this.preMuteVolume;
 2872+ this.muted = false;
 2873+ var percent = this.preMuteVolume;
28812874 } else {
28822875 this.muted = true;
2883 - this.preMuteVolume = this.volume;
 2876+ this.preMuteVolume = this.volume;
28842877 var percent = 0;
2885 - }
2886 - this.setVolume( percent );
 2878+ }
 2879+ this.setVolume( percent );
28872880 // Update the interface
28882881 this.setInterfaceVolume( percent );
28892882 },
2890 -
 2883+
28912884 /**
28922885 * Update volume function ( called from interface updates )
28932886 * @param {float} percent Percent of full volume
@@ -2896,77 +2889,77 @@
28972890 if( isNaN( percent ) ){
28982891 return ;
28992892 }
2900 - // Set the local volume attribute
 2893+ // Set the local volume attribute
29012894 this.previousVolume = this.volume = percent;
2902 -
 2895+
29032896 // Un-mute if setting positive volume
29042897 if( percent != 0 ){
2905 - this.muted = false;
 2898+ this.muted = false;
29062899 }
2907 -
2908 - // Update the playerElement volume
 2900+
 2901+ // Update the playerElement volume
29092902 this.setPlayerElementVolume( percent );
2910 -
2911 - //mw.log(" setVolume:: " + percent + ' this.volume is: ' + this.volume);
 2903+
 2904+ //mw.log(" setVolume:: " + percent + ' this.volume is: ' + this.volume);
29122905 $j( this ).trigger('volumeChanged', percent );
29132906 },
2914 -
 2907+
29152908 /**
29162909 * Updates the interface volume
29172910 * TODO should move to controlBuilder
29182911 * @param {float} percent Percentage volume to update interface
29192912 */
29202913 setInterfaceVolume: function( percent ) {
2921 - if( this.supports[ 'volumeControl' ] &&
2922 - this.$interface.find( '.volume-slider' ).length
 2914+ if( this.supports[ 'volumeControl' ] &&
 2915+ this.$interface.find( '.volume-slider' ).length
29232916 ) {
29242917 this.$interface.find( '.volume-slider' ).slider( 'value', percent * 100 );
29252918 }
2926 - },
2927 -
 2919+ },
 2920+
29282921 /**
29292922 * Abstract Update volume Method must be override by plug-in / player interface
29302923 */
29312924 setPlayerElementVolume: function( percent ) {
29322925 mw.log('Error player does not support volume adjustment' );
29332926 },
2934 -
 2927+
29352928 /**
29362929 * Abstract get volume Method must be override by plug-in / player interface
2937 - * (if player does not override we return the abstract player value )
 2930+ * (if player does not override we return the abstract player value )
29382931 */
29392932 getPlayerElementVolume: function(){
29402933 //mw.log(' error player does not support getting volume property' );
2941 - return this.volume;
 2934+ return this.volume;
29422935 },
2943 -
 2936+
29442937 /**
2945 - * Abstract get volume muted property must be overwritten by plug-in / player interface
2946 - * (if player does not override we return the abstract player value )
 2938+ * Abstract get volume muted property must be overwritten by plug-in / player interface
 2939+ * (if player does not override we return the abstract player value )
29472940 */
29482941 getPlayerElementMuted: function(){
29492942 //mw.log(' error player does not support getting mute property' );
29502943 return this.muted;
29512944 },
2952 -
 2945+
29532946 /**
29542947 * Passes a fullscreen request to the controlBuilder interface
29552948 */
29562949 fullscreen: function() {
2957 - this.controlBuilder.toggleFullscreen();
 2950+ this.controlBuilder.toggleFullscreen();
29582951 },
2959 -
 2952+
29602953 /**
2961 - * Abstract method to be run post embedding the player
2962 - * Generally should be overwritten by the plug-in / player
 2954+ * Abstract method to be run post embedding the player
 2955+ * Generally should be overwritten by the plug-in / player
29632956 */
29642957 postEmbedJS:function() {
29652958 return ;
29662959 },
2967 -
 2960+
29682961 /**
29692962 * Checks the player state based on thumbnail display & paused state
2970 - * @return {Boolean}
 2963+ * @return {Boolean}
29712964 * true if playing
29722965 * false if not playing
29732966 */
@@ -2981,34 +2974,34 @@
29822975 return true;
29832976 }
29842977 },
2985 -
 2978+
29862979 /**
29872980 * Get paused state
2988 - * @return {Boolean}
 2981+ * @return {Boolean}
29892982 * true if playing
29902983 * false if not playing
29912984 */
29922985 isPaused: function() {
29932986 return this.paused;
29942987 },
2995 -
 2988+
29962989 /**
29972990 * Get Stopped state
2998 - * @return {Boolean}
 2991+ * @return {Boolean}
29992992 * true if stopped
30002993 * false if playing
30012994 */
30022995 isStopped: function() {
30032996 return this.thumbnail_disp;
3004 - },
3005 -
 2997+ },
 2998+
30062999 // xxx temporary hack we need a better stop monitor system
30073000 stopMonitor: function(){
30083001 this.thumbnail_disp = true;
30093002 },
3010 -
 3003+
30113004 /**
3012 - * Checks if the currentTime was updated outside of
 3005+ * Checks if the currentTime was updated outside of
30133006 * the getPlayerElementTime function
30143007 */
30153008 checkForCurrentTimeSeek: function(){
@@ -3017,67 +3010,67 @@
30183011 if( _this.previousTime != _this.currentTime && !this.userSlide && !this.seeking){
30193012 // If the time has been updated and is in range issue a seek
30203013 if( _this.getDuration() && _this.currentTime <= _this.getDuration() ){
3021 - var seekPercent = _this.currentTime / _this.getDuration();
 3014+ var seekPercent = _this.currentTime / _this.getDuration();
30223015 mw.log("monitor::" + _this.previousTime + ' != ' +
30233016 _this.currentTime + " javascript based currentTime update to " + seekPercent);
3024 - this.doSeek( seekPercent );
 3017+ this.doSeek( seekPercent );
30253018 }
3026 - }
 3019+ }
30273020 },
3028 -
 3021+
30293022 /**
30303023 * Monitor playback and update interface components.
30313024 * underling plugin objects are responsible for updating currentTime
30323025 */
30333026 monitor: function() {
30343027 var _this = this;
3035 -
3036 - // Check for current time update outside of embed player
3037 - this.checkForCurrentTimeSeek();
3038 -
 3028+
 3029+ // Check for current time update outside of embed player
 3030+ this.checkForCurrentTimeSeek();
 3031+
30393032 // Update currentTime via embedPlayer
3040 - _this.currentTime = _this.getPlayerElementTime();
3041 -
 3033+ _this.currentTime = _this.getPlayerElementTime();
 3034+
30423035 // Update any offsets from server seek
30433036 if( _this.serverSeekTime && _this.supportsURLTimeEncoding ){
3044 - _this.currentTime = _this.serverSeekTime + _this.getPlayerElementTime()
 3037+ _this.currentTime = _this.serverSeekTime + _this.getPlayerElementTime();
30453038 }
30463039
30473040 // Update the previousTime ( so we can know if the user-javascript changed currentTime )
30483041 _this.previousTime = _this.currentTime;
3049 -
3050 -
 3042+
 3043+
30513044 // Check if volume was set outside of embed player function
3052 - //mw.log( ' this.volume: ' + _this.volume + ' prev Volume:: ' + _this.previousVolume );
3053 - if( Math.round( _this.volume * 100 ) != Math.round( _this.previousVolume * 100 ) ) {
 3045+ //mw.log( ' this.volume: ' + _this.volume + ' prev Volume:: ' + _this.previousVolume );
 3046+ if( Math.round( _this.volume * 100 ) != Math.round( _this.previousVolume * 100 ) ) {
30543047 _this.setInterfaceVolume( _this.volume );
30553048 $j( this ).trigger('volumeChanged', _this.volume );
30563049 }
3057 -
3058 - // Update the previous volume
3059 - _this.previousVolume = _this.volume;
3060 -
 3050+
 3051+ // Update the previous volume
 3052+ _this.previousVolume = _this.volume;
 3053+
30613054 // Update the volume from the player element
30623055 _this.volume = this.getPlayerElementVolume();
3063 -
 3056+
30643057 // update the mute state from the player element
30653058 if( _this.muted != _this.getPlayerElementMuted() && ! _this.isStopped() ){
30663059 mw.log( "EmbedPlayer::monitor: muted does not mach embed player" );
30673060 _this.toggleMute();
3068 - // Make sure they match:
3069 - _this.muted = _this.getPlayerElementMuted();
 3061+ // Make sure they match:
 3062+ _this.muted = _this.getPlayerElementMuted();
30703063 }
3071 -
3072 - //mw.log( 'Monitor:: ' + this.currentTime + ' duration: ' + ( parseInt( this.getDuration() ) + 1 ) + ' is seeking: ' + this.seeking );
3073 - if ( this.currentTime >= 0 && this.duration ) {
 3064+
 3065+ //mw.log( 'Monitor:: ' + this.currentTime + ' duration: ' + ( parseInt( this.getDuration() ) + 1 ) + ' is seeking: ' + this.seeking );
 3066+ if ( this.currentTime >= 0 && this.duration ) {
30743067 if ( !this.userSlide && !this.seeking ) {
3075 - if ( parseInt( this.startOffset ) != 0 ) {
3076 - // If start offset include that calculation
 3068+ if ( parseInt( this.startOffset ) != 0 ) {
 3069+ // If start offset include that calculation
30773070 this.updatePlayHead( ( this.currentTime - this.startOffset ) / this.duration );
30783071 var et = ( this.controlBuilder.longTimeDisp ) ? '/' + mw.seconds2npt( parseFloat( this.startOffset ) + parseFloat( this.duration ) ) : '';
30793072 this.controlBuilder.setStatus( mw.seconds2npt( this.currentTime ) + et );
3080 - } else {
3081 - this.updatePlayHead( this.currentTime / this.duration );
 3073+ } else {
 3074+ this.updatePlayHead( this.currentTime / this.duration );
30823075 // Only include the end time if longTimeDisp is enabled:
30833076 var et = ( this.controlBuilder.longTimeDisp ) ? '/' + mw.seconds2npt( this.duration ) : '';
30843077 this.controlBuilder.setStatus( mw.seconds2npt( this.currentTime ) + et );
@@ -3086,11 +3079,11 @@
30873080 // Check if we are "done"
30883081 var endPresentationTime = ( this.startOffset ) ? ( this.startOffset + this.duration ) : this.duration;
30893082 if ( this.currentTime >= endPresentationTime ) {
3090 - mw.log( "should run clip done :: " + this.currentTime + ' > ' + endPresentationTime );
 3083+ mw.log( "should run clip done :: " + this.currentTime + ' > ' + endPresentationTime );
30913084 this.onClipDone();
30923085 }
30933086 } else {
3094 - // Media lacks duration just show end time
 3087+ // Media lacks duration just show end time
30953088 if ( this.isStopped() ) {
30963089 this.controlBuilder.setStatus( this.getTimeRange() );
30973090 } else if ( this.isPaused() ) {
@@ -3104,107 +3097,107 @@
31053098 this.controlBuilder.setStatus( this.getTimeRange() );
31063099 }
31073100 }
3108 -
3109 - // Update buffer information
 3101+
 3102+ // Update buffer information
31103103 this.updateBufferStatus();
3111 -
 3104+
31123105 // run the "native" progress event on the virtual html5 object if set
31133106 if( this.progressEventData ) {
31143107 //mw.log("trigger:progress event on html5 proxy");
31153108 $j( this ).trigger( 'progress', this.progressEventData );
31163109 }
3117 -
3118 - // Call monitor at 250ms interval. ( use setInterval to avoid stacking monitor requests )
 3110+
 3111+ // Call monitor at 250ms interval. ( use setInterval to avoid stacking monitor requests )
31193112 if( ! this.isStopped() ) {
31203113 if( !this.monitorInterval ){
31213114 this.monitorInterval = setInterval( function(){
31223115 if( _this.monitor )
31233116 _this.monitor();
3124 - }, this.monitorRate )
 3117+ }, this.monitorRate );
31253118 }
31263119 } else {
3127 - // If stopped "stop" monitor:
 3120+ // If stopped "stop" monitor:
31283121 clearInterval( this.monitorInterval );
31293122 this.monitorInterval = 0;
31303123 }
3131 -
3132 - //mw.log('trigger:monitor:: ' + this.currentTime );
 3124+
 3125+ //mw.log('trigger:monitor:: ' + this.currentTime );
31333126 $j( this ).trigger( 'monitorEvent' );
3134 - },
3135 -
 3127+ },
 3128+
31363129 /**
3137 - * Abstract getPlayerElementTime function
 3130+ * Abstract getPlayerElementTime function
31383131 */
31393132 getPlayerElementTime: function(){
31403133 mw.log("Error: getPlayerElementTime should be implemented by embed library");
31413134 },
3142 -
 3135+
31433136 /**
31443137 * Update the Buffer status based on the local bufferedPercent var
31453138 */
31463139 updateBufferStatus: function() {
3147 -
3148 - // Get the buffer target based for playlist vs clip
3149 - $buffer = this.$interface.find( '.mw_buffer' );
 3140+
 3141+ // Get the buffer target based for playlist vs clip
 3142+ $buffer = this.$interface.find( '.mw_buffer' );
31503143 // Update the buffer progress bar (if available )
31513144 if ( this.bufferedPercent != 0 ) {
3152 - //mw.log('Update buffer css: ' + ( this.bufferedPercent * 100 ) + '% ' + $buffer.length );
 3145+ //mw.log('Update buffer css: ' + ( this.bufferedPercent * 100 ) + '% ' + $buffer.length );
31533146 if ( this.bufferedPercent > 1 ){
31543147 this.bufferedPercent = 1;
31553148 }
3156 -
 3149+
31573150 $buffer.css({
31583151 "width" : ( this.bufferedPercent * 100 ) + '%'
31593152 });
3160 - $j( this ).trigger( 'updateBufferPercent', this.bufferedPercent );
 3153+ $j( this ).trigger( 'updateBufferPercent', this.bufferedPercent );
31613154 } else {
31623155 $buffer.css( "width", '0px' );
31633156 }
3164 -
 3157+
31653158 // if we have not already run the buffer start hook
3166 - if( this.bufferedPercent > 0 && !this.bufferStartFlag ) {
 3159+ if( this.bufferedPercent > 0 && !this.bufferStartFlag ) {
31673160 this.bufferStartFlag = true;
31683161 mw.log("bufferStart");
31693162 $j( this ).trigger( 'bufferStartEvent' );
3170 - }
3171 -
 3163+ }
 3164+
31723165 // if we have not already run the buffer end hook
31733166 if( this.bufferedPercent == 1 && !this.bufferEndFlag){
3174 - this.bufferEndFlag = true;
 3167+ this.bufferEndFlag = true;
31753168 $j( this ).trigger( 'bufferEndEvent' );
31763169 }
31773170 },
3178 -
 3171+
31793172 /**
31803173 * Update the player playhead
31813174 *
31823175 * @param {Float} perc Value between 0 and 1 for position of playhead
31833176 */
3184 - updatePlayHead: function( perc ) {
 3177+ updatePlayHead: function( perc ) {
31853178 $playHead = this.$interface.find( '.play_head' );
3186 - if ( this.controls && $playHead.length != 0 ) {
 3179+ if ( this.controls && $playHead.length != 0 ) {
31873180 var val = parseInt( perc * 1000 );
31883181 $playHead.slider( 'value', val );
31893182 }
31903183 // @@todo should have 'progress' trigger the same as html5
31913184 $j( this ).trigger('updatePlayHeadPercent', perc);
31923185 },
3193 -
 3186+
31943187 /**
3195 - * Highlight a section of video on the playhead
 3188+ * Highlight a section of video on the playhead
31963189 *
31973190 * @param {Object} options Provides "start" time & "end" time to highlight
3198 - */
 3191+ */
31993192 highlightPlaySection:function( options ) {
32003193 mw.log( 'highlightPlaySection' );
32013194 var eid = ( this.pc ) ? this.pc.pp.id:this.id;
32023195 var dur = this.getDuration();
3203 - // set the left percet and update the slider:
 3196+ // set the left percet and update the slider:
32043197 rel_start_sec = mw.npt2seconds( options['start'] );
3205 - // remove the startOffset if relevent:
 3198+ // remove the startOffset if relevent:
32063199 if ( this.startOffset )
3207 - rel_start_sec = rel_start_sec - this.startOffset
3208 -
 3200+ rel_start_sec = rel_start_sec - this.startOffset;
 3201+
32093202 var slider_perc = 0;
32103203 if ( rel_start_sec <= 0 ) {
32113204 left_perc = 0;
@@ -3215,48 +3208,48 @@
32163209 left_perc = parseInt( ( rel_start_sec / dur ) * 100 ) ;
32173210 slider_perc = ( left_perc / 100 );
32183211 }
3219 -
 3212+
32203213 mw.log( "slider perc:" + slider_perc );
32213214 if ( ! this.isPlaying() ) {
32223215 this.updatePlayHead( slider_perc );
32233216 }
3224 -
 3217+
32253218 width_perc = parseInt( ( ( mw.npt2seconds( options['end'] ) - mw.npt2seconds( options['start'] ) ) / dur ) * 100 ) ;
32263219 if ( ( width_perc + left_perc ) > 100 ) {
32273220 width_perc = 100 - left_perc;
32283221 }
3229 - // mw.log('should hl: '+rel_start_sec+ '/' + dur + ' re:' + rel_end_sec+' lp:' + left_perc + ' width: ' + width_perc);
 3222+ // mw.log('should hl: '+rel_start_sec+ '/' + dur + ' re:' + rel_end_sec+' lp:' + left_perc + ' width: ' + width_perc);
32303223 $j( '#mv_seeker_' + eid + ' .mv_highlight' ).css( {
32313224 'left' : left_perc + '%',
32323225 'width' : width_perc + '%'
32333226 } ).show();
3234 -
3235 - this.jump_time = options['start'];
 3227+
 3228+ this.jump_time = options['start'];
32363229 this.serverSeekTime = mw.npt2seconds( options['start'] );
3237 - // trim output to
 3230+ // trim output to
32383231 this.controlBuilder.setStatus( gM( 'mwe-embedplayer-seek_to', mw.seconds2npt( this.serverSeekTime ) ) );
3239 - mw.log( 'DO update: ' + this.jump_time );
 3232+ mw.log( 'DO update: ' + this.jump_time );
32403233 this.updateThumbTime( rel_start_sec );
32413234 },
3242 -
 3235+
32433236 /**
32443237 * Hides the playhead highlight
3245 - */
 3238+ */
32463239 hideHighlight: function() {
32473240 var eid = ( this.pc ) ? this.pc.pp.id:this.id;
32483241 $j( '#mv_seeker_' + eid + ' .mv_highlight' ).hide();
3249 - this.controlBuilder.setStatus( this.getTimeRange() );
3250 - },
3251 -
3252 -
 3242+ this.controlBuilder.setStatus( this.getTimeRange() );
 3243+ },
 3244+
 3245+
32533246 /**
3254 - * Helper Functions for selected source
 3247+ * Helper Functions for selected source
32553248 */
3256 -
 3249+
32573250 /**
32583251 * Get the current selected media source
32593252 *
3260 - * @return src url
 3253+ * @return src url
32613254 */
32623255 getSrc: function() {
32633256 if( this.mediaElement.selectedSource ){
@@ -3264,7 +3257,7 @@
32653258 }
32663259 return false;
32673260 },
3268 -
 3261+
32693262 /**
32703263 * If the selected src supports URL time encoding
32713264 *
@@ -3276,7 +3269,7 @@
32773270 // do head request if on the same domain
32783271 return this.mediaElement.selectedSource.URLTimeEncoding;
32793272 }
3280 -}
 3273+};
32813274
32823275
32833276
@@ -3285,7 +3278,7 @@
32863279 *
32873280 * @param {String} id id used for the plugin.
32883281 * @param {Array} supported_types an array of supported MIME types.
3289 - * @param {String} library external script containing the plugin interface code.
 3282+ * @param {String} library external script containing the plugin interface code.
32903283 * @constructor
32913284 */
32923285 function mediaPlayer( id, supported_types, library )
@@ -3300,16 +3293,16 @@
33013294 mediaPlayer.prototype = {
33023295 // Id of the mediaPlayer
33033296 id:null,
3304 -
 3297+
33053298 // Mime types supported by this player
33063299 supported_types:null,
3307 -
3308 - // Player library ie: native, vlc, java etc.
 3300+
 3301+ // Player library ie: native, vlc, java etc.
33093302 library:null,
3310 -
 3303+
33113304 // Flag stores the mediaPlayer load state
33123305 loaded:false,
3313 -
 3306+
33143307 /**
33153308 * Checks support for a given MIME type
33163309 *
@@ -3317,7 +3310,7 @@
33183311 * @return {Boolean}
33193312 * true if mime type is supported
33203313 * false if mime type is unsupported
3321 - */
 3314+ */
33223315 supportsMIMEType: function( type ) {
33233316 for ( var i = 0; i < this.supported_types.length; i++ ) {
33243317 if ( this.supported_types[i] == type )
@@ -3325,20 +3318,20 @@
33263319 }
33273320 return false;
33283321 },
3329 -
 3322+
33303323 /**
33313324 * Get the "name" of the player from a predictable msg key
33323325 */
33333326 getName: function() {
33343327 return gM( 'mwe-embedplayer-ogg-player-' + this.id );
33353328 },
3336 -
 3329+
33373330 /**
33383331 * Loads the player library & player skin config ( if needed ) and then calls the callback.
33393332 *
33403333 * @param {Function} callback Function to be called once player library is loaded.
3341 - */
3342 - load: function( callback ) {
 3334+ */
 3335+ load: function( callback ) {
33433336 //Load player library ( upper case the first letter of the library )
33443337 mw.load( [
33453338 'mw.EmbedPlayer' + this.library.substr(0,1).toUpperCase() + this.library.substr(1)
@@ -3346,18 +3339,18 @@
33473340 callback();
33483341 } );
33493342 }
3350 -}
 3343+};
33513344
3352 -/**
3353 -* players and supported mime types
3354 -* In an ideal world we would query the plugin to get what mime
 3345+/**
 3346+* players and supported mime types
 3347+* In an ideal world we would query the plugin to get what mime
33553348 * types it supports in practice not always reliable/available
3356 -*
 3349+*
33573350 * We can't cleanly store these values per library since player library is loaded post player detection
3358 -*
 3351+*
33593352 */
33603353
3361 -//Flash based players:
 3354+//Flash based players:
33623355
33633356 var kplayer = new mediaPlayer('kplayer', ['video/x-flv', 'video/h264'], 'Kplayer');
33643357
@@ -3370,13 +3363,13 @@
33713364 var webmNativePlayer = new mediaPlayer( 'webmNative', ['video/webm'], 'Native' );
33723365
33733366 // VLC player
3374 -var vlcMineList = ['video/ogg', 'audio/ogg', 'application/ogg', 'video/x-flv', 'video/mp4', 'video/h264', 'video/x-msvideo', 'video/mpeg'];
 3367+var vlcMineList = ['video/ogg', 'audio/ogg', 'application/ogg', 'video/x-flv', 'video/mp4', 'video/h264', 'video/x-msvideo', 'video/mpeg'];
33753368 var vlcPlayer = new mediaPlayer( 'vlc-player', vlcMineList, 'Vlc' );
33763369
33773370 // Generic plugin
33783371 var oggPluginPlayer = new mediaPlayer( 'oggPlugin', ['video/ogg', 'application/ogg'], 'Generic' );
33793372
3380 -// HTML player for timed display of html content
 3373+// HTML player for timed display of html content
33813374 var htmlPlayer = new mediaPlayer( 'html', ['text/html', 'image/jpeg', 'image/png', 'image/svg'], 'Html' );
33823375
33833376
@@ -3393,13 +3386,13 @@
33943387 {
33953388 // The list of players supported
33963389 players : null,
3397 -
 3390+
33983391 // Store per mime-type prefrences for players
33993392 preference : { },
3400 -
 3393+
34013394 // Stores the default set of players for a given mime type
3402 - defaultPlayers : { },
3403 -
 3395+ defaultPlayers : { },
 3396+
34043397 /**
34053398 * Initializartion function sets the default order for players for
34063399 * a given mime type
@@ -3407,29 +3400,29 @@
34083401 init: function() {
34093402 this.players = new Array();
34103403 this.loadPreferences();
3411 -
3412 - // set up default players order for each library type
 3404+
 3405+ // set up default players order for each library type
34133406 this.defaultPlayers['video/x-flv'] = ['Kplayer', 'Vlc'];
34143407 this.defaultPlayers['video/h264'] = ['Native', 'Kplayer', 'Vlc'];
3415 -
 3408+
34163409 this.defaultPlayers['video/ogg'] = ['Native', 'Vlc', 'Java', 'Generic'];
34173410 this.defaultPlayers['application/ogg'] = ['Native', 'Vlc', 'Java', 'Generic'];
34183411 this.defaultPlayers['audio/ogg'] = ['Native', 'Vlc', 'Java' ];
34193412 this.defaultPlayers['video/mp4'] = ['Vlc'];
34203413 this.defaultPlayers['video/mpeg'] = ['Vlc'];
34213414 this.defaultPlayers['video/x-msvideo'] = ['Vlc'];
3422 -
 3415+
34233416 this.defaultPlayers['text/html'] = ['Html'];
34243417 this.defaultPlayers['image/jpeg'] = ['Html'];
34253418 this.defaultPlayers['image/png'] = ['Html'];
3426 - this.defaultPlayers['image/svg'] = ['Html'];
3427 -
 3419+ this.defaultPlayers['image/svg'] = ['Html'];
 3420+
34283421 },
3429 -
 3422+
34303423 /**
34313424 * Adds a Player to the player list
34323425 *
3433 - * @param {Object} player Player object to be added
 3426+ * @param {Object} player Player object to be added
34343427 */
34353428 addPlayer: function( player ) {
34363429 for ( var i = 0; i < this.players.length; i++ ) {
@@ -3438,12 +3431,12 @@
34393432 return ;
34403433 }
34413434 }
3442 -
3443 -
 3435+
 3436+
34443437 // Add the player:
34453438 this.players.push( player );
34463439 },
3447 -
 3440+
34483441 /**
34493442 * Checks if a player is supported by id
34503443 */
@@ -3455,17 +3448,17 @@
34563449 }
34573450 return false;
34583451 },
3459 -
 3452+
34603453 /**
34613454 * get players that support a given mimeType
34623455 *
34633456 * @param {String} mimeType Mime type of player set
3464 - * @return {Array}
 3457+ * @return {Array}
34653458 * Array of players that support a the requested mime type
34663459 */
34673460 getMIMETypePlayers: function( mimeType ) {
34683461 var mimePlayers = new Array();
3469 - var _this = this;
 3462+ var _this = this;
34703463 if ( this.defaultPlayers[mimeType] ) {
34713464 $j.each( this.defaultPlayers[ mimeType ], function( d, lib ) {
34723465 var library = _this.defaultPlayers[ mimeType ][ d ];
@@ -3478,16 +3471,16 @@
34793472 }
34803473 return mimePlayers;
34813474 },
3482 -
 3475+
34833476 /**
34843477 * Default player for a given mime type
34853478 *
34863479 * @param {String} mimeType Mime type of the requested player
3487 - * @return
 3480+ * @return
34883481 * Player for mime type
34893482 * null if no player found
34903483 */
3491 - defaultPlayer : function( mimeType ) {
 3484+ defaultPlayer : function( mimeType ) {
34923485 //mw.log( "get defaultPlayer for " + mimeType );
34933486 var mimePlayers = this.getMIMETypePlayers( mimeType );
34943487 if ( mimePlayers.length > 0 )
@@ -3504,59 +3497,59 @@
35053498 //mw.log( 'No default player found for ' + mimeType );
35063499 return null;
35073500 },
3508 -
 3501+
35093502 /**
35103503 * Sets the format preference.
35113504 *
3512 - * @param {String} mimeFormat Prefered format
 3505+ * @param {String} mimeFormat Prefered format
35133506 */
35143507 setFormatPreference : function ( mimeFormat ) {
35153508 this.preference['format_preference'] = mimeFormat;
3516 - mw.setUserConfig( 'playerPref', this.preference);
 3509+ mw.setUserConfig( 'playerPref', this.preference);
35173510 },
3518 -
 3511+
35193512 /**
35203513 * Sets the player preference
35213514 *
35223515 * @param {String} playerId Prefered player id
35233516 * @param {String} mimeType Mime type for the associated player stream
35243517 */
3525 - setPlayerPreference : function( playerId, mimeType ) {
3526 - var selectedPlayer = null;
 3518+ setPlayerPreference : function( playerId, mimeType ) {
 3519+ var selectedPlayer = null;
35273520 for ( var i = 0; i < this.players.length; i++ ) {
35283521 if ( this.players[i].id == playerId ) {
35293522 selectedPlayer = this.players[i];
35303523 mw.log( 'EmbedPlayer::setPlayerPreference: choosing ' + playerId + ' for ' + mimeType );
3531 - this.preference[ mimeType ] = playerId;
 3524+ this.preference[ mimeType ] = playerId;
35323525 mw.setUserConfig( 'playerPref', this.preference );
35333526 break;
35343527 }
35353528 }
3536 - // Update All the player instances:
 3529+ // Update All the player instances:
35373530 if ( selectedPlayer ) {
3538 - var playerList = mw.playerManager.getPlayerList();
 3531+ var playerList = mw.playerManager.getPlayerList();
35393532 for ( var i = 0; i < playerList.length; i++ ) {
35403533 var embed = $j( '#' + playerList[i] ).get( 0 );
35413534 if ( embed.mediaElement.selectedSource && ( embed.mediaElement.selectedSource.mimeType == mimeType ) )
35423535 {
35433536 embed.selectPlayer( selectedPlayer );
3544 - mw.log( 'EmbedPlayer::setPlayerPreference: using ' + embed.selectedPlayer.getName() + ' for ' + embed.mediaElement.selectedSource.getTitle() );
 3537+ mw.log( 'EmbedPlayer::setPlayerPreference: using ' + embed.selectedPlayer.getName() + ' for ' + embed.mediaElement.selectedSource.getTitle() );
35453538 }
35463539 }
35473540 }
35483541 },
3549 -
 3542+
35503543 /**
35513544 * Loads the user preference settings from a cookie
3552 - */
3553 - loadPreferences : function ( ) {
 3545+ */
 3546+ loadPreferences : function ( ) {
35543547 this.preference = { };
35553548 // see if we have a cookie set to a clientSupported type:
35563549 preferenceConfig = mw.getUserConfig( 'playerPref' );
35573550 if( typeof preferenceConfig == 'object' ) {
35583551 this.preference = preferenceConfig;
35593552 }
3560 - }
 3553+ }
35613554 };
35623555
35633556 /**
@@ -3568,62 +3561,62 @@
35693562
35703563 // List of players supported
35713564 players: null,
3572 -
3573 - // Detect flag for completion
 3565+
 3566+ // Detect flag for completion
35743567 detect_done:false,
3575 -
 3568+
35763569 /**
35773570 * Runs the detect method and update the detect_done flag
3578 - * @constructor
 3571+ * @constructor
35793572 */
35803573 init: function() {
3581 - // detect supported types
 3574+ // detect supported types
35823575 this.detect();
35833576 this.detect_done = true;
35843577 },
3585 -
 3578+
35863579 /**
35873580 * If the browsers supports a given mimetype
3588 - *
 3581+ *
35893582 * @param {String} mimeType Mime type for browser plug-in check
35903583 */
35913584 supportedMimeType: function( mimeType ) {
35923585 for ( var i =0; i < navigator.plugins.length; i++ ) {
35933586 var plugin = navigator.plugins[i];
35943587 if ( typeof plugin[ mimeType ] != "undefined" )
3595 - return true;
 3588+ return true;
35963589 }
35973590 return false;
35983591 },
3599 -
 3592+
36003593 /**
3601 - * Detects what plug-ins the client supports
 3594+ * Detects what plug-ins the client supports
36023595 */
3603 - detect: function() {
3604 - mw.log( "embedPlayer: running detect" );
3605 - this.players = new mediaPlayers();
 3596+ detect: function() {
 3597+ mw.log( "embedPlayer: running detect" );
 3598+ this.players = new mediaPlayers();
36063599 // every browser supports html rendering:
36073600 this.players.addPlayer( htmlPlayer );
36083601 // In Mozilla, navigator.javaEnabled() only tells us about preferences, we need to
3609 - // search navigator.mimeTypes to see if it's installed
 3602+ // search navigator.mimeTypes to see if it's installed
36103603 try{
36113604 var javaEnabled = navigator.javaEnabled();
36123605 } catch ( e ){
3613 -
 3606+
36143607 }
36153608 // Some browsers filter out duplicate mime types, hiding some plugins
36163609 var uniqueMimesOnly = $j.browser.opera || $j.browser.safari;
3617 -
 3610+
36183611 // Opera will switch off javaEnabled in preferences if java can't be found.
36193612 // And it doesn't register an application/x-java-applet mime type like Mozilla does.
36203613 if ( javaEnabled && ( navigator.appName == 'Opera' ) ) {
36213614 this.players.addPlayer( cortadoPlayer );
36223615 }
3623 -
 3616+
36243617 // ActiveX plugins
36253618 if ( $j.browser.msie ) {
3626 - // check for flash
3627 - if ( this.testActiveX( 'ShockwaveFlash.ShockwaveFlash' ) ) {
 3619+ // check for flash
 3620+ if ( this.testActiveX( 'ShockwaveFlash.ShockwaveFlash' ) ) {
36283621 this.players.addPlayer( kplayer );
36293622 //this.players.addPlayer( flowPlayer );
36303623 }
@@ -3631,52 +3624,52 @@
36323625 if ( this.testActiveX( 'VideoLAN.VLCPlugin.2' ) ) {
36333626 this.players.addPlayer( vlcPlayer );
36343627 }
3635 -
 3628+
36363629 // Java ActiveX
36373630 if ( this.testActiveX( 'JavaWebStart.isInstalled' ) ) {
36383631 this.players.addPlayer( cortadoPlayer );
36393632 }
3640 -
3641 - // quicktime (currently off)
 3633+
 3634+ // quicktime (currently off)
36423635 // if ( this.testActiveX( 'QuickTimeCheckObject.QuickTimeCheck.1' ) )
3643 - // this.players.addPlayer(quicktimeActiveXPlayer);
 3636+ // this.players.addPlayer(quicktimeActiveXPlayer);
36443637 }
36453638 // <video> element
36463639 if ( typeof HTMLVideoElement == 'object' // Firefox, Safari
36473640 || typeof HTMLVideoElement == 'function' ) // Opera
3648 - {
3649 - // Test what codecs the native player supports:
 3641+ {
 3642+ // Test what codecs the native player supports:
36503643 try {
36513644 var dummyvid = document.createElement( "video" );
36523645 if( dummyvid.canPlayType ) {
36533646 // Add the webm player
36543647 if( dummyvid.canPlayType('video/webm; codecs="vp8, vorbis"') ){
3655 - this.players.addPlayer( webmNativePlayer );
 3648+ this.players.addPlayer( webmNativePlayer );
36563649 }
3657 -
3658 - // Test for h264:
3659 - if ( dummyvid.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"' ) ) {
 3650+
 3651+ // Test for h264:
 3652+ if ( dummyvid.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"' ) ) {
36603653 this.players.addPlayer( h264NativePlayer );
36613654 }
36623655 // For now if Android assume we support h264Native (FIXME test on real devices )
36633656 if ( mw.isAndroid2() ){
36643657 this.players.addPlayer( h264NativePlayer );
36653658 }
3666 -
 3659+
36673660 // Test for ogg
3668 - if ( dummyvid.canPlayType( 'video/ogg; codecs="theora,vorbis"' ) ) {
3669 - this.players.addPlayer( oggNativePlayer );
 3661+ if ( dummyvid.canPlayType( 'video/ogg; codecs="theora,vorbis"' ) ) {
 3662+ this.players.addPlayer( oggNativePlayer );
36703663 // older versions of safari do not support canPlayType,
3671 - // but xiph qt registers mimetype via quicktime plugin
3672 - } else if ( this.supportedMimeType( 'video/ogg' ) ) {
 3664+ // but xiph qt registers mimetype via quicktime plugin
 3665+ } else if ( this.supportedMimeType( 'video/ogg' ) ) {
36733666 this.players.addPlayer( oggNativePlayer );
36743667 }
36753668 }
36763669 } catch ( e ) {
36773670 mw.log( 'could not run canPlayType ' + e );
3678 - }
3679 - }
3680 -
 3671+ }
 3672+ }
 3673+
36813674 // "navigator" plugins
36823675 if ( navigator.mimeTypes && navigator.mimeTypes.length > 0 ) {
36833676 for ( var i = 0; i < navigator.mimeTypes.length; i++ ) {
@@ -3695,17 +3688,17 @@
36963689 this.players.addPlayer( vlcPlayer );
36973690 continue;
36983691 }
3699 -
 3692+
37003693 if ( type == 'application/x-java-applet' ) {
37013694 this.players.addPlayer( cortadoPlayer );
37023695 continue;
37033696 }
3704 -
 3697+
37053698 if ( (type == 'video/mpeg' || type=='video/x-msvideo') &&
3706 - pluginName.toLowerCase() == 'vlc multimedia plugin' ) {
3707 - this.players.addPlayer( vlcMozillaPlayer );
3708 - }
3709 -
 3699+ pluginName.toLowerCase() == 'vlc multimedia plugin' ) {
 3700+ this.players.addPlayer( vlcMozillaPlayer );
 3701+ }
 3702+
37103703 if ( type == 'application/ogg' ) {
37113704 if ( pluginName.toLowerCase() == 'vlc multimedia plugin' ) {
37123705 this.players.addPlayer( vlcMozillaPlayer );
@@ -3724,35 +3717,35 @@
37253718 continue;
37263719 }
37273720 }
3728 -
 3721+
37293722 if ( type == 'application/x-shockwave-flash' ) {
3730 -
 3723+
37313724 this.players.addPlayer( kplayer );
37323725 //this.players.addPlayer( flowPlayer );
3733 -
 3726+
37343727 // check version to add omtk:
37353728 if( navigator.plugins["Shockwave Flash"] ){
37363729 var flashDescription = navigator.plugins["Shockwave Flash"].description;
37373730 var descArray = flashDescription.split( " " );
37383731 var tempArrayMajor = descArray[2].split( "." );
37393732 var versionMajor = tempArrayMajor[0];
3740 - // mw.log("version of flash: " + versionMajor);
 3733+ // mw.log("version of flash: " + versionMajor);
37413734 }
37423735 continue;
37433736 }
37443737 }
37453738 }
3746 -
3747 - // Allow extensions to detect and add their own "players"
 3739+
 3740+ // Allow extensions to detect and add their own "players"
37483741 mw.log("trigger::embedPlayerUpdateMediaPlayersEvent");
3749 - $j( mw ).trigger( 'embedPlayerUpdateMediaPlayersEvent' , this.players );
3750 -
 3742+ $j( mw ).trigger( 'embedPlayerUpdateMediaPlayersEvent' , this.players );
 3743+
37513744 },
3752 -
 3745+
37533746 /**
37543747 * Test IE for activeX by name
37553748 *
3756 - * @param {String} name Name of ActiveXObject to look for
 3749+ * @param {String} name Name of ActiveXObject to look for
37573750 */
37583751 testActiveX : function ( name ) {
37593752 mw.log("EmbedPlayer::detect: test testActiveX: " + name);
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/skins/kskin/mw.PlayerSkinKskin.js
@@ -4,109 +4,116 @@
55
66 mw.PlayerSkinKskin = {
77
8 - // The parent class for all kskin css:
 8+ // The parent class for all kskin css:
99 playerClass: 'k-player',
10 -
 10+
1111 // Display time string length
1212 longTimeDisp: false,
13 -
 13+
1414 // Default control bar height
15 - height: 20,
16 -
 15+ height: 20,
 16+
1717 // Volume control layout is horizontal
1818 volume_layout: 'horizontal',
19 -
 19+
2020 // Skin "kskin" is specific for wikimedia we have an
2121 // api Title key so the "credits" menu item can be showed.
2222 supportedMenuItems: {
2323 'credits': true
2424 },
25 -
 25+
2626 // Extends base components with kskin specific options:
2727 components: {
2828 'playButtonLarge' : {
2929 'h' : 55
30 - },
 30+ },
3131 'options': {
3232 'w':50,
33 - 'o':function( ctrlObj ) {
 33+ 'o':function( ctrlObj ) {
3434 return $j( '<div />' )
35 - .attr( 'title', gM( 'mwe-embedplayer-player_options' ) )
 35+ .attr( 'title', gM( 'mwe-embedplayer-player_options' ) )
3636 .addClass( "ui-state-default ui-corner-bl rButton k-options" )
37 - .append(
 37+ .append(
3838 $j( '<span />' )
39 - .text( gM( 'mwe-embedplayer-menu_btn' ) )
40 - )
 39+ .text( gM( 'mwe-embedplayer-menu_btn' ) )
 40+ );
4141 }
4242 },
4343 'volumeControl': {
4444 'w':40
45 - },
46 - // No attributionButton component for kSkin ( its integrated into the credits screen )
 45+ },
 46+ // No attributionButton component for kSkin ( its integrated into the credits screen )
4747 'attributionButton' : false,
48 -
49 - // Time display:
 48+
 49+ // Time display:
5050 'timeDisplay': {
5151 'w':45
52 - },
53 -
 52+ },
 53+
5454 'optionsMenu': {
5555 'w' : 0,
5656 'o' : function( ctrlObj ) {
57 - var embedPlayer = ctrlObj.embedPlayer;
58 -
59 - $menuOverlay = $j( '<div />')
 57+ var embedPlayer = ctrlObj.embedPlayer;
 58+
 59+ $menuOverlay = $j( '<div />')
6060 .addClass( 'overlay-win k-menu ui-widget-content' )
6161 .css( {
6262 'width' : '100%',
63 - 'position': 'absolute',
 63+ 'position': 'absolute',
6464 'top' : '0px',
6565 'bottom' : ( ctrlObj.getHeight() + 2 ) + 'px'
6666 } );
67 -
68 - // Setup menu offset ( if player height < getOverlayHeight )
69 - // This displays the menu outside of the player on small embeds
70 - if ( embedPlayer.getPlayerHeight() < ctrlObj.getOverlayHeight() ) {
 67+
 68+ // Note safari can't display video overlays with text:
 69+ // see bug https://bugs.webkit.org/show_bug.cgi?id=48379
 70+
 71+ var userAgent = navigator.userAgent.toLowerCase();
 72+ if( userAgent.indexOf('safari') != -1 ){
 73+ $menuOverlay.css('opacity', '0.9');
 74+ }
 75+ // Setup menu offset ( if player height < getOverlayHeight )
 76+ // This displays the menu outside of the player on small embeds
 77+ if ( embedPlayer.getPlayerHeight() < ctrlObj.getOverlayHeight() ) {
7178 var topPos = ( ctrlObj.checkOverlayControls() )
72 - ? embedPlayer.getPlayerHeight()
 79+ ? embedPlayer.getPlayerHeight()
7380 : embedPlayer.getPlayerHeight() + ctrlObj.getHeight();
74 -
75 - $menuOverlay.css( {
 81+
 82+ $menuOverlay.css( {
7683 'top' : topPos + 'px',
7784 'bottom' : null,
7885 'width' : ctrlObj.getOverlayWidth(),
79 - 'height' : ctrlObj.getOverlayHeight() + 'px'
 86+ 'height' : ctrlObj.getOverlayHeight() + 'px'
8087 });
81 - // Special common overflow hack for thumbnail display of player
 88+ // Special common overflow hack for thumbnail display of player
8289 $j( embedPlayer ).parents( '.thumbinner' ).css( 'overflow', 'visible' );
8390 }
84 -
 91+
8592 $menuBar = $j( '<ul />' )
8693 .addClass( 'k-menu-bar' );
87 -
 94+
8895 // dont include about player menu item ( FIXME should be moved to a init function )
8996 delete ctrlObj.supportedMenuItems['aboutPlayerLibrary'];
90 -
91 - // Output menu item containers:
 97+
 98+ // Output menu item containers:
9299 for ( var menuItem in ctrlObj.supportedMenuItems ) {
93 - $menuBar.append(
94 - $j( '<li />')
 100+ $menuBar.append(
 101+ $j( '<li />')
95102 // Add the menu item class:
96103 .addClass( 'k-' + menuItem + '-btn' )
97104 .attr( 'rel', menuItem )
98105 .append(
99106 $j( '<a />' )
100 - .attr( {
 107+ .attr( {
101108 'title' : gM( 'mwe-embedplayer-' + menuItem ),
102109 'href' : '#'
103110 })
104 - )
 111+ )
105112 );
106113 }
107 -
 114+
108115 // Add the menuBar to the menuOverlay
109116 $menuOverlay.append( $menuBar );
110 -
 117+
111118 var $menuScreens = $j( '<div />' )
112119 .addClass( 'k-menu-screens' )
113120 .css( {
@@ -116,86 +123,86 @@
117124 'bottom' : '0px',
118125 'right' : '45px',
119126 'overflow' : 'hidden'
120 - } )
 127+ } );
121128 for ( var menuItem in ctrlObj.supportedMenuItems ) {
122129 $menuScreens.append(
123130 $j( '<div />' )
124131 .addClass( 'menu-screen menu-' + menuItem )
125 - );
 132+ );
126133 }
127 -
 134+
128135 // Add the menuScreens to the menuOverlay
129136 $menuOverlay.append( $menuScreens );
130 -
131 - return $menuOverlay;
132 -
 137+
 138+ return $menuOverlay;
 139+
133140 }
134141 }
135142 },
136 -
 143+
137144 /**
138145 * Get minimal width for interface overlay
139146 */
140147 getOverlayWidth: function(){
141148 return ( this.embedPlayer.getPlayerWidth() < 200 )? 200 : this.embedPlayer.getPlayerWidth();
142 - },
143 -
 149+ },
 150+
144151 /**
145152 * Get minimal height for interface overlay
146153 */
147154 getOverlayHeight: function(){
148155 return ( this.embedPlayer.getPlayerHeight() < 160 )? 160 : this.embedPlayer.getPlayerHeight();
149156 },
150 -
 157+
151158 /**
152159 * Adds the skin Control Bindings
153160 */
154161 addSkinControlBindings: function() {
155162 var embedPlayer = this.embedPlayer;
156 - var _this = this;
157 -
 163+ var _this = this;
 164+
158165 // Set up control bar pointer
159166 this.$playerTarget = embedPlayer.$interface;
160 - // Set the menu target:
161 -
162 -
163 - // Options menu display:
 167+ // Set the menu target:
 168+
 169+
 170+ // Options menu display:
164171 this.$playerTarget.find( '.k-options' )
165172 .unbind()
166173 .click( function() {
167174 _this.checkMenuOverlay();
168 - var $kmenu = _this.$playerTarget.find( '.k-menu' );
 175+ var $kmenu = _this.$playerTarget.find( '.k-menu' );
169176 if ( $kmenu.is( ':visible' ) ) {
170177 _this.closeMenuOverlay( );
171178 } else {
172179 _this.showMenuOverlay( );
173180 }
174181 } );
175 -
 182+
176183 },
177184 /**
178 - * checks for menu overlay and runs menu bindings if unset
179 - */
 185+ * checks for menu overlay and runs menu bindings if unset
 186+ */
180187 checkMenuOverlay: function(){
181188 var _this = this;
182189 var embedPlayer = this.embedPlayer;
183 - if ( _this.$playerTarget.find( '.k-menu' ).length == 0 ) {
 190+ if ( _this.$playerTarget.find( '.k-menu' ).length == 0 ) {
184191 // Stop the player if it does not support overlays:
185192 if ( !embedPlayer.supports['overlays'] ) {
186193 embedPlayer.stop();
187194 }
188 -
 195+
189196 // Add the menu binding
190 - _this.addMeunBinding();
 197+ _this.addMenuBinding();
191198 }
192199 },
193 -
 200+
194201 /**
195202 * Close the menu overlay
196203 */
197204 closeMenuOverlay: function( ) {
198 - mw.log("PlayerSkin: close menu overlay" );
199 -
 205+ mw.log("PlayerSkin: close menu overlay" );
 206+
200207 var $optionsMenu = this.$playerTarget.find( '.k-options' );
201208 var $kmenu = this.$playerTarget.find( '.k-menu' );
202209 $kmenu.fadeOut( "fast", function() {
@@ -204,80 +211,80 @@
205212 } );
206213 this.$playerTarget.find( '.play-btn-large' ).fadeIn( 'fast' );
207214
208 - // re display the control bar if hidden:
 215+ // re display the control bar if hidden:
209216 this.showControlBar();
210 -
211 - // Set close overlay menu flag:
 217+
 218+ // Set close overlay menu flag:
212219 this.displayOptionsMenuFlag = false;
213220 },
214 -
 221+
215222 /**
216223 * Show the menu overlay
217224 */
218225 showMenuOverlay: function( $ktxt ) {
219226 var $optionsMenu = this.$playerTarget.find( '.k-options' );
220227 var $kmenu = this.$playerTarget.find( '.k-menu' );
221 -
 228+
222229 $kmenu.fadeIn( "fast", function() {
223230 $optionsMenu.find( 'span' )
224231 .text ( gM( 'mwe-embedplayer-close_btn' ) );
225232 } );
226233 this.$playerTarget.find( '.play-btn-large' ).fadeOut( 'fast' );
227 -
 234+
228235 $j(this.embedPlayer).trigger( 'displayMenuOverlay' );
229 -
 236+
230237 // Set the Options Menu display flag to true:
231238 this.displayOptionsMenuFlag = true;
232239 },
233 -
 240+
234241 /**
235242 * Adds binding for the options menu
236243 *
237 - * @param {Object} $tp Target video container for
 244+ * @param {Object} $tp Target video container for
238245 */
239 - addMeunBinding: function() {
 246+ addMenuBinding: function() {
240247 var _this = this;
241248 var embedPlayer = this.embedPlayer;
242249 // Set local player target pointer:
243250 var $playerTarget = embedPlayer.$interface;
244 -
 251+
245252 // Check if k-menu already exists:
246253 if ( $playerTarget.find( '.k-menu' ).length != 0 )
247254 return false;
248 -
249 - // Add options menu to top of player target children:
 255+
 256+ // Add options menu to top of player target children:
250257 $playerTarget.prepend(
251 - _this.getComponent( 'optionsMenu' )
252 - );
253 -
 258+ _this.getComponent( 'optionsMenu' )
 259+ );
 260+
254261 // By default its hidden:
255262 $playerTarget.find( '.k-menu' ).hide();
256 -
257 - // Add menu-items bindings:
 263+
 264+ // Add menu-items bindings:
258265 for ( var menuItem in _this.supportedMenuItems ) {
259266 $playerTarget.find( '.k-' + menuItem + '-btn' ).click( function( ) {
260 -
 267+
261268 // Grab the context from the "clicked" menu item
262269 var mk = $j( this ).attr( 'rel' );
263 -
264 - // hide all menu items
265 - $targetItem = $playerTarget.find( '.menu-' + mk );
266 -
 270+
 271+ // hide all menu items
 272+ $targetItem = $playerTarget.find( '.menu-' + mk );
 273+
267274 // call the function showMenuItem
268275 _this.showMenuItem( mk );
269 -
270 - // Hide the others
 276+
 277+ // Hide the others
271278 $playerTarget.find( '.menu-screen' ).hide();
272 -
 279+
273280 // Show the target menu item:
274281 $targetItem.fadeIn( "fast" );
275 -
 282+
276283 // Don't follow the # link
277284 return false;
278285 } );
279286 }
280287 },
281 -
 288+
282289 /**
283290 * onClipDone action
284291 * onClipDone for k-skin (with apiTitleKey) show the "credits" screen:
@@ -285,58 +292,58 @@
286293 onClipDone: function(){
287294 if( this.embedPlayer.apiTitleKey ){
288295 this.checkMenuOverlay( );
289 - this.showMenuOverlay();
 296+ this.showMenuOverlay();
290297 this.showMenuItem( 'credits' );
291298 }
292299 },
293 -
 300+
294301 /**
295302 * Shows a selected menu_item
296303 *
297 - * NOTE: this should be merged with parent mw.PlayerControlBuilder optionMenuItems
 304+ * NOTE: this should be merged with parent mw.PlayerControlBuilder optionMenuItems
298305 * binding mode
299 - *
 306+ *
300307 * @param {String} menu_itme Menu item key to display
301308 */
302 - showMenuItem:function( menuItem ) {
 309+ showMenuItem:function( menuItem ) {
303310 var embedPlayer = this.embedPlayer;
304 - //handle special k-skin specific display;
 311+ //handle special k-skin specific display;
305312 switch( menuItem ){
306313 case 'credits':
307 - this.showCredits();
 314+ this.showCredits();
308315 break;
309316 case 'playerSelect':
310 - embedPlayer.$interface.find( '.menu-playerSelect').html(
 317+ embedPlayer.$interface.find( '.menu-playerSelect').html(
311318 this.getPlayerSelect()
312 - );
313 - break;
 319+ );
 320+ break;
314321 case 'download' :
315 - embedPlayer.$interface.find( '.menu-download').text(
316 - gM('mwe-loading_txt' )
 322+ embedPlayer.$interface.find( '.menu-download').text(
 323+ gM('mwe-loading_txt' )
317324 );
318325 // Call show download with the target to be populated
319326 this.showDownload(
320 - embedPlayer.$interface.find( '.menu-download')
 327+ embedPlayer.$interface.find( '.menu-download')
321328 );
322329 break;
323330 case 'share':
324331 embedPlayer.$interface.find( '.menu-share' ).html(
325332 this.getShare()
326333 );
327 - break;
328 - }
 334+ break;
 335+ }
329336 },
330 -
 337+
331338 /**
332339 * Show the credit screen ( presently specific to kaltura skin )
333 - */
 340+ */
334341 showCredits: function() {
335 - // Set up the shortcuts:
 342+ // Set up the shortcuts:
336343 var embedPlayer = this.embedPlayer;
337 - var _this = this;
 344+ var _this = this;
338345 var $target = embedPlayer.$interface.find( '.menu-credits' );
339346
340 - $target.empty().append(
 347+ $target.empty().append(
341348 $j('<h2 />')
342349 .text( gM( 'mwe-embedplayer-credits' ) ),
343350 $j('<div />')
@@ -344,8 +351,8 @@
345352 .loadingSpinner()
346353 );
347354
348 - if( mw.getConfig( 'EmbedPlayer.KalturaAttribution' ) == true ){
349 - $target.append(
 355+ if( mw.getConfig( 'EmbedPlayer.KalturaAttribution' ) == true ){
 356+ $target.append(
350357 $j( '<div />' )
351358 .addClass( 'k-attribution' )
352359 .attr({
@@ -356,95 +363,95 @@
357364 })
358365 );
359366 }
360 -
 367+
361368 if( !embedPlayer.apiTitleKey ){
362369 $target.find('.credits_box').text(
363 - 'Error: no title key to grab credits with'
 370+ 'Error: no title key to grab credits with'
364371 );
365372 return ;
366373 }
367 -
368 - _this.getCredits();
 374+
 375+ _this.getCredits();
369376 },
370 -
 377+
371378 /**
372379 * Issues a request to populate the credits box
373380 */
374381 getCredits: function(){
375382 // Setup shortcuts:
376383 var embedPlayer = this.embedPlayer;
377 - var _this = this;
 384+ var _this = this;
378385 var $target = embedPlayer.$interface.find( '.menu-credits' );
379 -
380 - var apiUrl = mw.getApiProviderURL( embedPlayer.apiProvider );
 386+
 387+ var apiUrl = mw.getApiProviderURL( embedPlayer.apiProvider );
381388 var fileTitle = 'File:' + embedPlayer.apiTitleKey.replace(/File:|Image:/, '');
382 -
 389+
383390 // Get the image info
384 - var request = {
 391+ var request = {
385392 'prop' : 'imageinfo',
386393 'titles' : fileTitle,
387 - 'iiprop' : 'url'
 394+ 'iiprop' : 'url'
388395 };
389396 var articleUrl = '';
390 - mw.getJSON( apiUrl, request, function( data ){
 397+ mw.getJSON( apiUrl, request, function( data ){
391398 if ( data.query.pages ) {
392399 for ( var i in data.query.pages ) {
393400 var imageProps = data.query.pages[i];
394 - // Check properties for "missing"
395 - if( imageProps.imageinfo && imageProps.imageinfo[0] && imageProps.imageinfo[0].descriptionurl ){
396 - // Found page
 401+ // Check properties for "missing"
 402+ if( imageProps.imageinfo && imageProps.imageinfo[0] && imageProps.imageinfo[0].descriptionurl ){
 403+ // Found page
397404 $target.find( '.credits_box' ).html(
398405 _this.doCreditLine( imageProps.imageinfo[0].descriptionurl )
399 - );
 406+ );
400407 }else{
401 - // missing page descriptionurl
 408+ // missing page descriptionurl
402409 $target.find( '.credits_box' ).text(
403 - 'Error: title key: ' + embedPlayer.apiTitleKey + ' not found'
404 - );
 410+ 'Error: title key: ' + embedPlayer.apiTitleKey + ' not found'
 411+ );
405412 }
406413 }
407414 }
408 - } );
 415+ } );
409416 },
410 -
 417+
411418 /**
412419 * Build a clip credit from the resource wikiText page
413420 *
414421 * NOTE: in the future this should parse the resource page template
415 - *
 422+ *
416423 * @parm {String} wikiText Resource wiki text page contents
417424 */
418425 doCreditLine: function ( articleUrl ){
419426 var embedPlayer = this.embedPlayer;
420 -
421 - // Get the title str
422 - var titleStr = embedPlayer.apiTitleKey.replace(/_/g, ' ');
423 -
 427+
 428+ // Get the title str
 429+ var titleStr = embedPlayer.apiTitleKey.replace(/_/g, ' ');
 430+
424431 var imgWidth = ( this.getOverlayWidth() < 250 )? 45 : 90;
425 -
 432+
426433 return $j( '<div/>' ).addClass( 'creditline' )
427434 .append(
428435 $j('<a/>').attr({
429436 'href' : articleUrl,
430 - 'title' : titleStr
431 - }).html(
 437+ 'title' : titleStr
 438+ }).html(
432439 $j('<img/>').attr( {
433 - 'border': 0,
434 - 'src' : embedPlayer.poster
 440+ 'border': 0,
 441+ 'src' : embedPlayer.poster
435442 } ).css( {
436443 'width' : imgWidth,
437444 'height': parseInt( imgWidth * ( embedPlayer.height / embedPlayer.width ) )
438445 } )
439446 )
440447 )
441 - .append(
442 - $j('<span>').html(
443 - gM( 'mwe-embedplayer-credit-title' ,
 448+ .append(
 449+ $j('<span>').html(
 450+ gM( 'mwe-embedplayer-credit-title' ,
444451 // We use a div container to easialy get at the built out link
445 - $j('<div>').html(
 452+ $j('<div>').html(
446453 $j('<a/>').attr({
447454 'href' : articleUrl,
448 - 'title' : titleStr
 455+ 'title' : titleStr
449456 }).text( titleStr )
450457 ).html()
451458 )
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/skins/mw.PlayerControlBuilder.js
@@ -1,5 +1,5 @@
22 /**
3 -* Msg text is inherited from embedPlayer
 3+* Msg text is inherited from embedPlayer
44 */
55
66 ( function( mw ) {
@@ -15,189 +15,183 @@
1616 * ControlsBuilder prototype:
1717 */
1818 mw.PlayerControlBuilder.prototype = {
19 - //Default Local values:
20 -
 19+ //Default Local values:
 20+
2121 // Parent css Class name
2222 playerClass : 'mv-player',
23 -
 23+
2424 // Long string display of time value
2525 longTimeDisp: true,
26 -
 26+
2727 // Default volume layout is "vertical"
2828 volume_layout : 'vertical',
29 -
 29+
3030 // Default control bar height
31 - height: 31,
32 -
 31+ height: 31,
 32+
3333 // Default supported components is merged with embedPlayer set of supported types
34 - supportedComponets: {
35 - // All playback types support options
36 - 'options': true
37 - },
38 -
 34+ supportedComponets: {
 35+ // All playback types support options
 36+ 'options': true
 37+ },
 38+
3939 // Default supported menu items is merged with skin menu items
4040 supportedMenuItems: {
4141 // Player Select
42 - 'playerSelect' : true,
43 -
 42+ 'playerSelect' : true,
 43+
4444 // Download the file menu
45 - 'download' : true,
46 -
 45+ 'download' : true,
 46+
4747 // Share the video menu
4848 'share' : true,
49 -
 49+
5050 // Player library link
5151 'aboutPlayerLibrary': true
52 - },
53 -
 52+ },
 53+
5454 // Flag to store the current fullscreen mode
5555 fullscreenMode: false,
56 -
57 - // Flag to store if a warning binding has been added
 56+
 57+ // Flag to store if a warning binding has been added
5858 addWarningFlag: false,
59 -
60 - // Flag to store state of overlay on player
61 - displayOptionsMenuFlag: false,
62 -
 59+
 60+ // Flag to store state of overlay on player
 61+ displayOptionsMenuFlag: false,
 62+
6363 /**
6464 * Initialization Object for the control builder
6565 *
6666 * @param {Object} embedPlayer EmbedPlayer interface
67 - */
 67+ */
6868 init: function( embedPlayer ) {
6969 var _this = this;
7070 this.embedPlayer = embedPlayer;
7171
7272 // Check for skin overrides for controlBuilder
73 - var skinClass = embedPlayer.skinName.substr(0,1).toUpperCase() + embedPlayer.skinName.substr( 1 );
74 - if ( mw['PlayerSkin' + skinClass ]) {
75 -
 73+ var skinClass = embedPlayer.skinName.substr(0,1).toUpperCase() + embedPlayer.skinName.substr( 1 );
 74+ if ( mw['PlayerSkin' + skinClass ]) {
 75+
7676 // Clone as to not override prototype with the skin config
77 - var _this = $j.extend( true, { }, this, mw['PlayerSkin' + skinClass ] );
 77+ var _this = $j.extend( true, { }, this, mw['PlayerSkin' + skinClass ] );
7878 return _this;
7979 }
80 - // Return the controlBuilder Object:
 80+ // Return the controlBuilder Object:
8181 return this;
8282 },
83 -
 83+
8484 /**
8585 * Get the control bar height
86 - * @return {Number} control bar height
 86+ * @return {Number} control bar height
8787 */
8888 getHeight: function(){
8989 return this.height;
9090 },
91 -
 91+
9292 /**
9393 * Add the controls html to palyer interface
9494 */
9595 addControls: function() {
9696 // Set up local pointer to the embedPlayer
9797 var embedPlayer = this.embedPlayer;
98 -
 98+
9999 // Set up local controlBuilder
100100 var _this = this;
101101
102 - // Remove any old controls & old overlays:
 102+ // Remove any old controls & old overlays:
103103 embedPlayer.$interface.find( '.control-bar,.overlay-win' ).remove();
104 -
105 - // Reset flag:
 104+
 105+ // Reset flag:
106106 _this.displayOptionsMenuFlag = false;
107 -
108 -
 107+
 108+
109109 // Setup the controlBar container
110110 var $controlBar = $j('<div />')
111111 .addClass( 'ui-state-default ui-widget-header ui-helper-clearfix control-bar' )
112 - .css( 'height', this.height );
113 -
 112+ .css( 'height', this.height );
 113+
114114 $controlBar.css( {
115115 'position': 'absolute',
116116 'bottom' : '0px',
117117 'left' : '0px',
118118 'right' : '0px'
119119 } );
120 - // Check for overlay controls:
121 - if( _this.checkOverlayControls() ) {
122 - $controlBar.hide();
123 - // Make sure the interface is correct height:
124 - embedPlayer.$interface.css( {
125 - 'height' : parseInt( embedPlayer.height )
126 - } );
127 - } else {
 120+ // Check for overlay controls:
 121+ if( ! _this.checkOverlayControls() ) {
128122 // Add some space to interface for the control bar ( if not overlaying controls )
129123 embedPlayer.$interface.css( {
130124 'height' : parseInt( embedPlayer.height ) + parseInt( this.height ) +2
131 - } );
 125+ } );
132126 }
133 -
 127+
134128 // Add the controls to the interface
135129 embedPlayer.$interface.append( $controlBar );
136 -
 130+
137131 // Add the Controls Component
138132 this.addControlComponents();
139 -
 133+
140134 // Add top level Controls bindings
141135 this.addControlBindings();
142136 },
143 -
 137+
144138 /**
145139 * Add control components as defined per this.components
146 - */
 140+ */
147141 addControlComponents: function( ) {
148 - var _this = this;
 142+ var _this = this;
149143 mw.log( 'PlayerControlsBuilder:: addControlComponents' );
150 -
 144+
151145 // Set up local pointer to the embedPlayer
152146 var embedPlayer = this.embedPlayer;
153 -
 147+
154148 //Set up local var to control container:
155 - var $controlBar = embedPlayer.$interface.find( '.control-bar' );
156 -
 149+ var $controlBar = embedPlayer.$interface.find( '.control-bar' );
 150+
157151 this.available_width = embedPlayer.getPlayerWidth();
158 -
 152+
159153 // Make pointer to the embedPlayer
160154 this.embedPlayer = embedPlayer;
161 -
 155+
162156 // Build the supportedComponets list
163157 this.supportedComponets = $j.extend( this.supportedComponets, embedPlayer.supports );
164 -
 158+
165159 // Check for timed text support:
166160 if( embedPlayer.isTimedTextSupported() ){
167161 this.supportedComponets['timedText'] = true;
168 - }
169 - // Check for Attribution button
 162+ }
 163+ // Check for Attribution button
170164 if( mw.getConfig( 'EmbedPlayer.AttributionButton' ) && embedPlayer.attributionbutton ){
171165 this.supportedComponets[ 'attributionButton' ] = true;
172166 }
173 -
 167+
174168 // Check global fullscreen enabled flag
175169 if( mw.getConfig( 'EmbedPlayer.EnableFullscreen' ) === false ){
176 - this.supportedComponets[ 'fullscreen'] = false;
 170+ this.supportedComponets[ 'fullscreen'] = false;
177171 }
178172
179 - // Output components
180 - for ( var component_id in this.components ) {
181 - // Check for (component === false ) and skip
182 - if( this.components[ component_id ] === false ){
 173+ // Output components
 174+ for ( var component_id in this.components ) {
 175+ // Check for (component === false ) and skip
 176+ if( this.components[ component_id ] === false ){
183177 continue;
184178 }
185 -
 179+
186180 // Special case with playhead skip if we have > 30px of space for it
187181 if ( component_id == 'playHead' && this.available_width < 30 ){
188182 continue;
189 - }
190 -
191 - // Skip "fullscreen" button for assets or where height is 0px ( audio )
192 - if( component_id == 'fullscreen' && this.embedPlayer.height == 0 ){
 183+ }
 184+
 185+ // Skip "fullscreen" button for assets or where height is 0px ( audio )
 186+ if( component_id == 'fullscreen' && this.embedPlayer.height == 0 ){
193187 continue;
194 - }
195 -
 188+ }
 189+
196190 // Make sure the given components is supported:
197191 if ( this.supportedComponets[ component_id ] ) {
198 - if ( this.available_width > this.components[ component_id ].w ) {
 192+ if ( this.available_width > this.components[ component_id ].w ) {
199193 // Append the component
200 - $controlBar.append(
201 - _this.getComponent( component_id )
 194+ $controlBar.append(
 195+ _this.getComponent( component_id )
202196 );
203197 this.available_width -= this.components[ component_id ].w;
204198 } else {
@@ -206,28 +200,28 @@
207201 }
208202 }
209203 },
210 -
 204+
211205 /**
212206 * Get the fullscreen player css
213 - */
 207+ */
214208 getFullscreenPlayerCss: function() {
215209 var embedPlayer = this.embedPlayer;
216 - // Setup target height width based on max window size
 210+ // Setup target height width based on max window size
217211 var fullWidth = $j( window ).width() - 2 ;
218 - var fullHeight = $j( window ).height() ;
219 -
 212+ var fullHeight = $j( window ).height() ;
 213+
220214 // Set target width
221215 var targetWidth = fullWidth;
222 - var targetHeight = targetWidth * ( embedPlayer.getHeight() / embedPlayer.getWidth() );
223 - // Check if it exceeds the height constraint:
224 - if( targetHeight > fullHeight ){
225 - targetHeight = fullHeight;
226 - targetWidth = targetHeight * ( embedPlayer.getWidth() / embedPlayer.getHeight() );
 216+ var targetHeight = targetWidth * ( embedPlayer.getHeight() / embedPlayer.getWidth() );
 217+ // Check if it exceeds the height constraint:
 218+ if( targetHeight > fullHeight ){
 219+ targetHeight = fullHeight;
 220+ targetWidth = targetHeight * ( embedPlayer.getWidth() / embedPlayer.getHeight() );
227221 }
228222 var offsetTop = ( targetHeight < fullHeight )? ( fullHeight- targetHeight ) / 2 : 0;
229223 var offsetLeft = ( targetWidth < fullWidth )? ( fullWidth- targetWidth ) / 2 : 0;
230 -
231 - //mw.log(" targetWidth: " + targetWidth + ' fullwidth: ' + fullWidth + ' :: ' + ( fullWidth- targetWidth ) / 2 );
 224+
 225+ //mw.log(" targetWidth: " + targetWidth + ' fullwidth: ' + fullWidth + ' :: ' + ( fullWidth- targetWidth ) / 2 );
232226 return {
233227 'height': targetHeight,
234228 'width' : targetWidth,
@@ -235,159 +229,159 @@
236230 'left': offsetLeft
237231 };
238232 },
239 -
 233+
240234 /**
241235 * Get the fullscreen play button css
242236 */
243 - getFullscreenPlayButtonCss: function() {
 237+ getFullscreenPlayButtonCss: function() {
244238 var pos = this.getFullscreenPlayerCss();
245239 return {
246 - 'left' : ( ( pos.width - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ),
 240+ 'left' : ( ( pos.width - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ),
247241 'top' : ( ( pos.height - this.getComponentHeight( 'playButtonLarge' ) ) / 2 )
248242 };
249243 },
250 -
 244+
251245 /**
252246 * Get the fullscreen text css
253247 */
254248 getInterfaceSizeTextCss: function() {
255249 // Some arbitrary scale relative to window size ( 400px wide is text size 105% )
256 - var textSize = this.embedPlayer.$interface.width() / 3.8;
257 - if( textSize < 95 ) textSize = 95;
 250+ var textSize = this.embedPlayer.$interface.width() / 3.8;
 251+ if( textSize < 95 ) textSize = 95;
258252 if( textSize > 200 ) textSize = 200;
259253 //mw.log(' win size is: ' + $j( window ).width() + ' ts: ' + textSize );
260254 return {
261255 'font-size' : textSize + '%'
262256 };
263257 },
264 -
 258+
265259 /**
266 - * Toggles full screen by calling
 260+ * Toggles full screen by calling
267261 * doFullScreenPlayer to enable fullscreen mode
268262 * restoreWindowPlayer to restore window mode
269263 */
270264 toggleFullscreen: function() {
271265 if( this.fullscreenMode ){
272 - this.restoreWindowPlayer();
273 - $j( this.embedPlayer ).trigger( 'closeFullScreenEvent' );
 266+ this.restoreWindowPlayer();
 267+ $j( this.embedPlayer ).trigger( 'closeFullScreenEvent' );
274268 }else{
275269 this.doFullScreenPlayer();
276 - $j( this.embedPlayer ).trigger( 'openFullScreenEvent' );
 270+ $j( this.embedPlayer ).trigger( 'openFullScreenEvent' );
277271 }
278272 },
279 -
 273+
280274 /**
281 - * Do full-screen mode
282 - */
 275+ * Do full-screen mode
 276+ */
283277 doFullScreenPlayer: function() {
284 - mw.log(" controlBuilder :: toggle full-screen ");
 278+ mw.log(" controlBuilder :: toggle full-screen ");
285279 // Setup pointer to control builder :
286280 var _this = this;
287 -
288 - // Setup local reference to embed player:
 281+
 282+ // Setup local reference to embed player:
289283 var embedPlayer = this.embedPlayer;
290 -
291 - // Setup a local reference to the player interface:
 284+
 285+ // Setup a local reference to the player interface:
292286 var $interface = embedPlayer.$interface;
293 -
294 -
 287+
 288+
295289 // Check fullscreen state ( if already true do nothing )
296290 if( this.fullscreenMode == true ){
297291 return ;
298 - }
299 - this.fullscreenMode = true;
300 -
 292+ }
 293+ this.fullscreenMode = true;
 294+
301295 //Remove any old mw-fullscreen-overlay
302296 $interface.find( '.mw-fullscreen-overlay' ).remove();
303 -
 297+
304298 // Special hack for mediawiki monobook skin search box
305 - if( $j( '#p-search,#p-logo' ).length ) {
306 - $j( '#p-search,#p-logo,#ca-nstab-project a' ).css('z-index', 1);
307 - }
308 -
 299+ if( $j( '#p-search,#p-logo' ).length ) {
 300+ $j( '#p-search,#p-logo,#ca-nstab-project a' ).css('z-index', 1);
 301+ }
 302+
309303 // Add the css fixed fullscreen black overlay as a sibling to the video element
310 - $interface.after(
 304+ $interface.after(
311305 $j( '<div />' )
312306 .addClass( 'mw-fullscreen-overlay' )
313307 // Set some arbitrary high z-index
314 - .css('z-index', mw.getConfig( 'EmbedPlayer.fullScreenZIndex' ) )
 308+ .css('z-index', mw.getConfig( 'EmbedPlayer.fullScreenZIndex' ) )
315309 .hide()
316310 .fadeIn("slow")
317 - );
318 -
319 - // Change the interface to absolute positioned:
 311+ );
 312+
 313+ // Change the interface to absolute positioned:
320314 this.windowPositionStyle = $interface.css( 'position' );
321315 this.windowZindex = $interface.css( 'z-index' );
322 -
323 - // Get the base offset:
 316+
 317+ // Get the base offset:
324318 this.windowOffset = $interface.offset();
325319 this.windowOffset.top = this.windowOffset.top - $j(document).scrollTop();
326320 this.windowOffset.left = this.windowOffset.left - $j(document).scrollLeft();
327 -
 321+
328322 // Change the z-index of the interface
329323 $interface.css( {
330324 'position' : 'fixed',
331325 'z-index' : mw.getConfig( 'EmbedPlayer.fullScreenZIndex' ) + 1,
332326 'top' : this.windowOffset.top,
333327 'left' : this.windowOffset.left
334 - } );
335 -
 328+ } );
 329+
336330 // Empty out the parent absolute index
337 - _this.parentsAbsolute = [];
338 -
 331+ _this.parentsAbsolute = [];
 332+
339333 // Hide the body scroll bar
340334 $j('body').css( 'overflow', 'hidden' );
341 -
342335
 336+
343337 var topOffset = '0px';
344338 var leftOffset = '0px';
345 -
 339+
346340 //Check if we have an offsetParent
347341 if( $interface.offsetParent().get(0).tagName.toLowerCase() != 'body' ) {
348342 topOffset = -this.windowOffset.top + 'px';
349343 leftOffset = -this.windowOffset.left + 'px';
350 - }
351 -
352 - // Resize interface container
353 - $interface.animate( {
 344+ }
 345+
 346+ // Resize interface container
 347+ $interface.animate( {
354348 'top' : topOffset,
355349 'left' : leftOffset,
356350 'width' : $j( window ).width(),
357 - 'height' : $j( window ).height(),
358 - 'overlow' : 'hidden'
 351+ 'height' : $j( window ).height(),
 352+ 'overlow' : 'hidden'
359353 }, function(){
360354 // Remove absolute css of the interface parents
361355 $interface.parents().each( function() {
362 - //mw.log(' parent : ' + $j( this ).attr('id' ) + ' class: ' + $j( this ).attr('class') + ' pos: ' + $j( this ).css( 'position' ) );
363 - if( $j( this ).css( 'position' ) == 'absolute' ) {
364 - _this.parentsAbsolute.push( $j( this ) );
 356+ //mw.log(' parent : ' + $j( this ).attr('id' ) + ' class: ' + $j( this ).attr('class') + ' pos: ' + $j( this ).css( 'position' ) );
 357+ if( $j( this ).css( 'position' ) == 'absolute' ) {
 358+ _this.parentsAbsolute.push( $j( this ) );
365359 $j( this ).css( 'position', null );
366 - mw.log(' should update position: ' + $j( this ).css( 'position' ) );
 360+ mw.log(' should update position: ' + $j( this ).css( 'position' ) );
367361 }
368362 } );
369 -
370 - // Resize the timed text font size per new player width
371 - $interface.find( '.track' ).css( _this.getInterfaceSizeTextCss() );
 363+
 364+ // Resize the timed text font size per new player width
 365+ $interface.find( '.track' ).css( _this.getInterfaceSizeTextCss() );
372366 } );
373 -
374 - // Set the player height width:
 367+
 368+ // Set the player height width:
375369 $j( embedPlayer ).css( {
376370 'position' : 'relative'
377371 } )
378372 // Animate a zoom ( while keeping aspect )
379373 .animate( _this.getFullscreenPlayerCss() );
380 -
381 -
 374+
 375+
382376 // Reposition play-btn-large ( this is unfortunately not easy to position with 'margin': 'auto'
383377 $interface.find('.play-btn-large').animate( _this.getFullscreenPlayButtonCss() );
384 -
 378+
385379 // Bind mouse move in interface to hide control bar
386380 _this.mouseMovedFlag = false;
387381 $interface.mousemove( function(e){
388 - _this.mouseMovedFlag = true;
 382+ _this.mouseMovedFlag = true;
389383 });
390384 // Check every 2 seconds reset flag status:
391 - function checkMovedMouse(){
 385+ function checkMovedMouse(){
392386 if( _this.fullscreenMode ){
393387 if( _this.mouseMovedFlag ){
394388 _this.mouseMovedFlag = false;
@@ -398,34 +392,34 @@
399393 // Check for mouse movement every 250ms
400394 _this.hideControlBar();
401395 setTimeout(checkMovedMouse, 250 );
402 - }
 396+ }
403397 }
404398 };
405399 checkMovedMouse();
406 -
 400+
407401 // Bind Scroll position update
408 -
 402+
409403 // Bind resize resize window to resize window
410404 $j( window ).resize( function() {
411405 if( _this.fullscreenMode ){
412 - // Update interface container:
413 - $interface.css( {
 406+ // Update interface container:
 407+ $interface.css( {
414408 'top' : '0px',
415409 'left' : '0px',
416410 'width' : $j( window ).width(),
417 - 'height' : $j( window ).height()
 411+ 'height' : $j( window ).height()
418412 } );
419413 // Update player size
420414 $j( embedPlayer ).css( _this.getFullscreenPlayerCss() );
421 -
 415+
422416 // Update play button pos
423 - $interface.find('.play-btn-large').css( _this.getFullscreenPlayButtonCss() );
424 -
425 - // Update the timed text size
 417+ $interface.find('.play-btn-large').css( _this.getFullscreenPlayButtonCss() );
 418+
 419+ // Update the timed text size
426420 $interface.find( '.track' ).css( _this.getInterfaceSizeTextCss() );
427421 }
428422 });
429 -
 423+
430424 // Bind escape to restore clip resolution
431425 $j( window ).keyup( function(event) {
432426 // Escape check
@@ -433,90 +427,91 @@
434428 _this.restoreWindowPlayer();
435429 }
436430 } );
437 - },
438 -
 431+ },
 432+
439433 /**
440434 * Restore the window player
441435 */
442 - restoreWindowPlayer: function() {
 436+ restoreWindowPlayer: function() {
443437 var _this = this;
444438 var embedPlayer = this.embedPlayer;
445 -
 439+
446440 // Check fullscreen state
447441 if( this.fullscreenMode == false ){
448 - return ;
 442+ return ;
449443 }
450444 // Set fullscreen mode to false
451445 this.fullscreenMode = false;
452 -
453 - var $interface = embedPlayer.$interface;
454 - var interfaceHeight = ( _this.checkOverlayControls() )
455 - ? embedPlayer.getHeight()
 446+
 447+ var $interface = embedPlayer.$interface;
 448+ var interfaceHeight = ( _this.checkOverlayControls() )
 449+ ? embedPlayer.getHeight()
456450 : embedPlayer.getHeight() + _this.getHeight();
457 -
 451+
458452 mw.log( 'restoreWindowPlayer:: h:' + interfaceHeight + ' w:' + embedPlayer.getWidth());
459453 $j('.mw-fullscreen-overlay').fadeOut( 'slow' );
460 -
461 - // Restore interface:
 454+
 455+ // Restore interface:
462456 $interface.animate( {
463457 'top' : this.windowOffset.top,
464458 'left' : this.windowOffset.left,
465 - // height is embedPlayer height + controlBuilder height:
 459+ // height is embedPlayer height + controlBuilder height:
466460 'height' : interfaceHeight,
467 - 'width' : embedPlayer.getWidth()
468 - },function(){
469 - // Restore non-absolute layout:
 461+ 'width' : embedPlayer.getWidth()
 462+ },function(){
 463+ // Restore non-absolute layout:
470464 $interface.css( {
471465 'position' : _this.windowPositionStyle,
472466 'z-index' : _this.windowZindex,
473467 'overlow' : 'visible',
474468 'top' : null,
475 - 'left' : null
476 - } );
477 -
478 - // Restore absolute layout of parents:
479 - $j.each( _this.parentsAbsolute, function( na, element ){
 469+ 'left' : null
 470+ } );
 471+
 472+ // Restore absolute layout of parents:
 473+ $j.each( _this.parentsAbsolute, function( na, element ){
480474 $j( element ).css( 'position', 'absolute' );
481475 } );
482476 _this.parentsAbsolute = null;
483 -
 477+
484478 // Restore the body scroll bar
485479 $j('body').css( 'overflow', 'auto' );
486 -
487 - // Resize the timed text font size per window width
 480+
 481+ // Resize the timed text font size per window width
488482 $interface.find( '.track' ).css( _this.getInterfaceSizeTextCss() );
489 -
 483+
490484 } );
491485 mw.log( 'restore embedPlayer:: ' + embedPlayer.getWidth() + ' h: ' + embedPlayer.getHeight());
492 - // Restore the player:
 486+ // Restore the player:
493487 $j( embedPlayer ).animate( {
494488 'top' : '0px',
495489 'left' : '0px',
496490 'width' : embedPlayer.getWidth(),
497491 'height' : embedPlayer.getHeight()
498492 });
 493+
499494 // Restore the play button
500495 $interface.find('.play-btn-large').animate( {
501 - 'left' : ( ( embedPlayer.getPlayerWidth() - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ),
502 - 'top' : ( ( embedPlayer.getPlayerHeight() -this.getComponentHeight( 'playButtonLarge' ) ) / 2 )
 496+ 'left' : ( ( embedPlayer.getWidth() - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ),
 497+ 'top' : ( ( embedPlayer.getHeight() -this.getComponentHeight( 'playButtonLarge' ) ) / 2 )
503498 } );
504 -
 499+
505500 },
506 -
 501+
507502 /**
508503 * Get minimal width for interface overlay
509504 */
510505 getOverlayWidth: function( ) {
511506 return ( this.embedPlayer.getPlayerWidth() < 300 )? 300 : this.embedPlayer.getPlayerWidth();
512 - },
513 -
 507+ },
 508+
514509 /**
515510 * Get minimal height for interface overlay
516511 */
517512 getOverlayHeight: function( ) {
518513 return ( this.embedPlayer.getPlayerHeight() < 200 )? 200 : this.embedPlayer.getPlayerHeight();
519514 },
520 -
 515+
521516 /**
522517 * addControlBindings
523518 * Adds control hooks once controls are in the DOM
@@ -524,28 +519,28 @@
525520 addControlBindings: function( ) {
526521 // Set up local pointer to the embedPlayer
527522 var embedPlayer = this.embedPlayer;
528 - var _this = this;
 523+ var _this = this;
529524 var $interface = embedPlayer.$interface;
530 -
 525+
531526 // Remove any old interface bindings
532527 $interface.unbind();
533 -
534 - // Add hide show bindings for control overlay (if overlay is enabled )
 528+
 529+ // Add hide show bindings for control overlay (if overlay is enabled )
535530 if( ! _this.checkOverlayControls() ) {
536 - $interface.show();
537 - } else { // hide show controls:
 531+ $interface.show();
 532+ } else { // hide show controls:
538533 //$interface.css({'background-color': 'red'});
539534 // Bind a startTouch to show controls
540535 $interface.bind( 'touchstart', function() {
541536 _this.showControlBar();
542 - // ( once the user touched the video "don't hide" )
543 - } );
544 - // Add a special absolute overlay for hover ( to keep menu displayed
 537+ // ( once the user touched the video "don't hide" )
 538+ } );
 539+ // Add a special absolute overlay for hover ( to keep menu displayed
545540 $interface.hoverIntent({
546541 'sensitivity': 4,
547542 'timeout' : 2000,
548 - 'over' : function(){
549 - // Show controls with a set timeout ( avoid fade in fade out on short mouse over )
 543+ 'over' : function(){
 544+ // Show controls with a set timeout ( avoid fade in fade out on short mouse over )
550545 _this.showControlBar();
551546 },
552547 'out' : function(){
@@ -553,66 +548,66 @@
554549 }
555550 });
556551 }
557 -
 552+
558553 // Add recommend firefox if we have non-native playback:
559 - if ( _this.checkNativeWarning( ) ) {
 554+ if ( _this.checkNativeWarning( ) ) {
560555 _this.doWarningBindinng(
561556 'EmbedPlayer.ShowNativeWarning',
562 - gM( 'mwe-embedplayer-for_best_experience' )
 557+ gM( 'mwe-embedplayer-for_best_experience' )
563558 );
564559 }
565 -
 560+
566561 // Do png fix for ie6
567 - if ( $j.browser.msie && $j.browser.version <= 6 ) {
 562+ if ( $j.browser.msie && $j.browser.version <= 6 ) {
568563 $j('#' + embedPlayer.id + ' .play-btn-large' ).pngFix();
569564 }
570 -
 565+
571566 this.doVolumeBinding();
572 -
 567+
573568 // Check if we have any custom skin Bindings to run
574569 if ( this.addSkinControlBindings && typeof( this.addSkinControlBindings ) == 'function' ){
575570 this.addSkinControlBindings();
576571 }
577 -
578 - mw.log('tirgger::addControlBindingsEvent');
 572+
 573+ mw.log('trigger::addControlBindingsEvent');
579574 $j( embedPlayer ).trigger( 'addControlBindingsEvent');
580575 },
581 -
 576+
582577 /**
583 - * Hide the control bar.
 578+ * Hide the control bar.
584579 */
585580 hideControlBar : function(){
586581 var animateDuration = 'slow';
587 - var _this = this;
588 -
 582+ var _this = this;
 583+
589584 // Do not hide control bar if overlay menu item is being displayed:
590 - if( _this.displayOptionsMenuFlag ||
 585+ if( _this.displayOptionsMenuFlag ||
591586 $j( '#timedTextMenu_' + this.embedPlayer.id ).is( ':visible' ) ) {
592587 setTimeout( function(){
593588 _this.hideControlBar();
594589 }, 200 );
595590 return ;
596591 }
597 -
598 -
 592+
 593+
599594 // Hide the control bar
600595 this.embedPlayer.$interface.find( '.control-bar')
601596 .fadeOut( animateDuration );
602 -
603 - // Move the timed text XXX this should go into timedText module
 597+
 598+ // Move the timed text XXX this should go into timedText module
604599 this.embedPlayer.$interface.find( '.track' )
605600 .stop()
606 - .animate( {
607 - 'bottom' : 10
 601+ .animate( {
 602+ 'bottom' : 10
608603 }, 'slow' );
609 -
 604+
610605 },
611 -
 606+
612607 /**
613608 * Show the control bar
614609 */
615610 showControlBar: function(){
616 - var animateDuration = 'slow';
 611+ var animateDuration = 'slow';
617612 if(! this.embedPlayer )
618613 return ;
619614 if( this.embedPlayer.getPlayerElement ){
@@ -621,105 +616,109 @@
622617 mw.log( 'PlayerControlBuilder:: ShowControlBar' );
623618 // Move up text track if present
624619 this.embedPlayer.$interface.find( '.track' )
625 - .animate(
626 - {
627 - 'bottom' : this.getHeight() + 10
628 - },
 620+ .animate(
 621+ {
 622+ 'bottom' : this.getHeight() + 10
 623+ },
629624 animateDuration
630 - );
631 -
 625+ );
 626+
632627 // Show interface controls
633628 this.embedPlayer.$interface.find( '.control-bar' )
634 - .fadeIn( animateDuration );
 629+ .fadeIn( animateDuration );
635630 },
636 -
 631+
637632 /**
638 - * Checks if the browser supports overlays and the controlsOverlay is
 633+ * Checks if the browser supports overlays and the controlsOverlay is
639634 * set to true for the player or via config
640635 */
641636 checkOverlayControls: function(){
642 - //if the player "supports" overlays:
 637+
 638+ //if the player "supports" overlays:
643639 if( ! this.embedPlayer.supports['overlays'] ){
644640 return false;
645641 }
646 -
 642+
647643 // If disabled via the player
648644 if( this.embedPlayer.overlaycontrols === false ){
649645 return false;
650 - }
651 -
 646+ }
 647+
652648 // If the config is false
653649 if( mw.getConfig( 'EmbedPlayer.OverlayControls' ) == false){
654650 return false;
655 - }
656 -
657 - // don't hide controls when content "height" is 0 ( audio tags )
658 - if( this.embedPlayer.getPlayerHeight() == 0 ){
 651+ }
 652+
 653+ // Don't hide controls when content "height" is 0px ( audio tags )
 654+ if( this.embedPlayer.getPlayerHeight() === 0 &&
 655+ $j(this.embedPlayer).css('height').indexOf('%') == -1 ){
659656 return false;
660 - }
 657+ }
661658 if( this.embedPlayer.controls === false ){
662659 return false;
663660 }
664 - // Past all tests OverlayControls is true:
665 - return true;
 661+ // Past all tests OverlayControls is true:
 662+ return true;
666663 },
667 -
 664+
668665 /**
669 - * Check if a warning should be issued to non-native playback systems
 666+ * Check if a warning should be issued to non-native playback systems
670667 *
671 - * dependent on mediaElement being setup
672 - */
673 - checkNativeWarning: function( ) {
 668+ * dependent on mediaElement being setup
 669+ */
 670+ checkNativeWarning: function( ) {
674671 if( mw.getConfig( 'EmbedPlayer.ShowNativeWarning' ) === false ){
675672 return false;
676673 }
677 -
 674+
678675 // If the resolution is too small don't display the warning
679676 if( this.embedPlayer.getPlayerHeight() < 199 ){
680677 return false;
681 - }
 678+ }
682679 // See if we have we have ogg support
683680 var supportingPlayers = mw.EmbedTypes.players.getMIMETypePlayers( 'video/ogg' );
684681 for ( var i = 0; i < supportingPlayers.length; i++ ) {
685 -
686 - if ( supportingPlayers[i].id == 'oggNative'
687 - &&
 682+
 683+ if ( supportingPlayers[i].id == 'oggNative'
 684+ &&
688685 // xxx google chrome has broken oggNative playback:
689686 // http://code.google.com/p/chromium/issues/detail?id=56180
690 - ! /chrome/.test(navigator.userAgent.toLowerCase() )
 687+ ! /chrome/.test(navigator.userAgent.toLowerCase() )
691688 ){
692689 return false;
693690 }
694691 }
695 -
696 - // Check for h264 and or flash/flv source and playback support and don't show warning
697 - if(
698 - ( mw.EmbedTypes.players.getMIMETypePlayers( 'video/h264' ).length
 692+
 693+ // Check for h264 and or flash/flv source and playback support and don't show warning
 694+ if(
 695+ ( mw.EmbedTypes.players.getMIMETypePlayers( 'video/h264' ).length
699696 && this.embedPlayer.mediaElement.getSources( 'video/h264' ).length )
700697 ||
701 - ( mw.EmbedTypes.players.getMIMETypePlayers( 'video/x-flv' ).length
702 - && this.embedPlayer.mediaElement.getSources( 'video/x-flv' ).length )
 698+ ( mw.EmbedTypes.players.getMIMETypePlayers( 'video/x-flv' ).length
 699+ && this.embedPlayer.mediaElement.getSources( 'video/x-flv' ).length )
703700 ){
704701 // No firefox link if a h.264 or flash/flv stream is present
705702 return false;
706703 }
707 -
 704+
708705 // Should issue the native warning
709706 return true;
710707 },
711 -
 708+
712709 /**
713710 * Does a native warning check binding to the player on mouse over.
714711 * @param {string} preferenceId The preference Id
715 - * @param {object} warningMsg The jQuery object warning message to be displayed.
716 - *
 712+ * @param {object} warningMsg The jQuery object warning message to be displayed.
 713+ *
717714 */
718715 doWarningBindinng: function( preferenceId, warningMsg ) {
719 - mw.log( 'controlBuilder: doWarningBindinng: ' + preferenceId + ' wm: ' + warningMsg);
 716+ mw.log( 'controlBuilder: doWarningBindinng: ' + preferenceId + ' wm: ' + warningMsg);
720717 // Set up local pointer to the embedPlayer
721718 var embedPlayer = this.embedPlayer;
722 - var _this = this;
723 -
 719+ var _this = this;
 720+
 721+ // make sure the
 722+
724723 $j( embedPlayer ).hoverIntent({
725724 'timeout': 2000,
726725 'over': function() {
@@ -727,12 +726,12 @@
728727 if( embedPlayer.isPlaying() ){
729728 return ;
730729 }
731 - if ( $j( '#warningOverlay_' + embedPlayer.id ).length == 0 ) {
732 -
 730+ if ( $j( '#warningOverlay_' + embedPlayer.id ).length == 0 ) {
 731+
733732 $j( this ).append(
734733 $j('<div />')
735734 .attr( {
736 - 'id': "warningOverlay_" + embedPlayer.id
 735+ 'id': "warningOverlay_" + embedPlayer.id
737736 } )
738737 .addClass( 'ui-state-highlight ui-corner-all' )
739738 .css({
@@ -745,64 +744,62 @@
746745 'right' : '10px',
747746 'padding' : '4px'
748747 })
749 - .html( warningMsg )
 748+ .html( warningMsg )
750749 );
751 -
752 - $targetWarning = $j( '#warningOverlay_' + embedPlayer.id );
753 -
754 - $targetWarning.append(
 750+
 751+ $targetWarning = $j( '#warningOverlay_' + embedPlayer.id );
 752+
 753+ $targetWarning.append(
755754 $j('<br />')
756 - );
757 -
758 - $targetWarning.append(
 755+ );
 756+
 757+ $targetWarning.append(
759758 $j( '<input />' )
760759 .attr({
761760 'id' : 'ffwarn_' + embedPlayer.id,
762761 'type' : "checkbox",
763762 'name' : 'ffwarn_' + embedPlayer.id
764 - })
 763+ })
765764 .click( function() {
766 - if ( $j( this ).is( ':checked' ) ) {
767 - // Set up a cookie for 7 days:
768 - $j.cookie( preferenceId, false, { expires: 7 } );
769 - // Set the current instance
770 - mw.setConfig( preferenceId, false );
771 - $j( '#warningOverlay_' + embedPlayer.id ).fadeOut( 'slow' );
772 - // set the local prefrence to false
773 - _this.addWarningFlag = false;
774 - } else {
775 - mw.setConfig( preferenceId, true );
776 - $j.cookie( preferenceId, true );
777 - }
778 - } )
 765+ mw.log("WarningBindinng:: set " + preferenceId + ' to hidewarning ' );
 766+ // Set up a cookie for 30 days:
 767+ $j.cookie( preferenceId, 'hidewarning', { expires: 30 } );
 768+ // Set the current instance
 769+ mw.setConfig( preferenceId, false );
 770+ $j( '#warningOverlay_' + embedPlayer.id ).fadeOut( 'slow' );
 771+ // set the local prefrence to false
 772+ _this.addWarningFlag = false;
 773+ } )
779774 );
780 - $targetWarning.append(
781 - $j('<span />')
 775+ $targetWarning.append(
 776+ $j('<label />')
782777 .text( gM( 'mwe-embedplayer-do_not_warn_again' ) )
 778+ .attr( 'for', 'ffwarn_' + embedPlayer.id )
783779 );
784 - }
 780+ }
785781 // Check the global config before showing the warning
786 - if ( mw.getConfig( preferenceId ) === true ){
 782+ if ( mw.getConfig( preferenceId ) === true && $j.cookie( preferenceId ) != 'hidewarning' ){
 783+ mw.log("WarningBindinng:: show warning " + mw.getConfig( preferenceId ) + ' cookie: '+ $j.cookie( preferenceId ) + 'typeof:' + typeof $j.cookie( preferenceId ));
787784 $j( '#warningOverlay_' + embedPlayer.id ).fadeIn( 'slow' );
788 - }
 785+ };
789786 },
790 - 'out': function() {
 787+ 'out': function() {
791788 $j( '#warningOverlay_' + embedPlayer.id ).fadeOut( 'slow' );
792789 }
793790 });
794791 },
795 -
 792+
796793 /**
797794 * Binds the volume controls
798795 */
799796 doVolumeBinding: function( ) {
800797 var embedPlayer = this.embedPlayer;
801 - var _this = this;
 798+ var _this = this;
802799 embedPlayer.$interface.find( '.volume_control span' ).unbind().buttonHover().click( function() {
803800 mw.log( 'Volume control toggle' );
804801 embedPlayer.toggleMute();
805802 } );
806 -
 803+
807804 // Add vertical volume display hover
808805 if ( this.volume_layout == 'vertical' ) {
809806 // Default volume binding:
@@ -828,7 +825,7 @@
829826 }
830827 );
831828 }
832 -
 829+
833830 // Setup volume slider:
834831 var sliderConf = {
835832 range: "min",
@@ -847,153 +844,153 @@
848845 } else {
849846 embedPlayer.$interface.find( '.volume_control span' ).removeClass( 'ui-icon-volume-off' ).addClass( 'ui-icon-volume-on' );
850847 }
851 - mw.log('change::update volume:' + percent);
 848+ mw.log('change::update volume:' + percent);
852849 embedPlayer.setVolume( percent );
853850 }
854851 };
855 -
 852+
856853 if ( this.volume_layout == 'vertical' ) {
857854 sliderConf[ 'orientation' ] = "vertical";
858855 }
859 -
 856+
860857 embedPlayer.$interface.find( '.volume-slider' ).slider( sliderConf );
861858 },
862 -
 859+
863860 /**
864861 * Get the options menu ul with li menu items
865862 */
866863 getOptionsMenu: function( ) {
867864 $optionsMenu = $j( '<ul />' );
868865 for( var i in this.optionMenuItems ){
869 -
870 - // Make sure its supported in the current controlBuilder config:
 866+
 867+ // Make sure its supported in the current controlBuilder config:
871868 if( ! this.supportedMenuItems[ i ] ) {
872869 continue;
873870 }
874 -
 871+
875872 $optionsMenu.append(
876873 this.optionMenuItems[i]( this )
877874 );
878 - }
 875+ }
879876 return $optionsMenu;
880 - },
881 -
 877+ },
 878+
882879 /**
883880 * Allow the controlBuilder to do interface actions onDone
884881 */
885882 onClipDone: function(){
886 - // Related videos could be shown here
 883+ // Related videos could be shown here
887884 },
888 -
 885+
889886 /**
890 - * The ctrl builder updates the interface on seeking
 887+ * The ctrl builder updates the interface on seeking
891888 */
892889 onSeek: function(){
893890 //mw.log( "controlBuilder:: onSeek" );
894 - // Update the interface:
 891+ // Update the interface:
895892 this.setStatus( gM( 'mwe-embedplayer-seeking' ) );
896893 },
897 -
 894+
898895 /**
899 - * Updates the player status that displays short text msgs and the play clock
 896+ * Updates the player status that displays short text msgs and the play clock
900897 * @param {String} value Status string value to update
901898 */
902899 setStatus: function( value ) {
903900 // update status:
904901 this.embedPlayer.$interface.find( '.time-disp' ).text( value );
905902 },
906 -
907 - /**
 903+
 904+ /**
908905 * Option menu items
909906 *
910907 * @return
911 - * 'li' a li line item with click action for that menu item
 908+ * 'li' a li line item with click action for that menu item
912909 */
913 - optionMenuItems: {
 910+ optionMenuItems: {
914911 // Player select menu item
915912 'playerSelect': function( ctrlObj ){
916 - return $j.getLineItem(
 913+ return $j.getLineItem(
917914 gM( 'mwe-embedplayer-choose_player' ),
918915 'gear',
919916 function( ) {
920 - ctrlObj.displayMenuOverlay(
 917+ ctrlObj.displayMenuOverlay(
921918 ctrlObj.getPlayerSelect()
922 - );
 919+ );
923920 }
924921 );
925 - },
926 -
 922+ },
 923+
927924 // Download the file menu
928925 'download': function( ctrlObj ) {
929 - return $j.getLineItem(
 926+ return $j.getLineItem(
930927 gM( 'mwe-embedplayer-download' ),
931928 'disk',
932929 function( ) {
933 - ctrlObj.displayMenuOverlay( gM('mwe-loading_txt' ) );
 930+ ctrlObj.displayMenuOverlay( gM('mwe-loading_txt' ) );
934931 // Call show download with the target to be populated
935 - ctrlObj.showDownload(
936 - ctrlObj.embedPlayer.$interface.find( '.overlay-content' )
937 - );
 932+ ctrlObj.showDownload(
 933+ ctrlObj.embedPlayer.$interface.find( '.overlay-content' )
 934+ );
938935 $j( ctrlObj.embedPlayer ).trigger( 'showDownloadEvent' );
939936 }
940937 );
941 - },
942 -
 938+ },
 939+
943940 // Share the video menu
944941 'share': function( ctrlObj ) {
945 - return $j.getLineItem(
 942+ return $j.getLineItem(
946943 gM( 'mwe-embedplayer-share' ),
947944 'mail-closed',
948945 function( ) {
949 - ctrlObj.displayMenuOverlay(
 946+ ctrlObj.displayMenuOverlay(
950947 ctrlObj.getShare()
951 - );
 948+ );
952949 $j( ctrlObj.embedPlayer ).trigger( 'showShareEvent' );
953950 }
954951 );
955 - },
956 -
 952+ },
 953+
957954 'aboutPlayerLibrary' : function( ctrlObj ){
958 - return $j.getLineItem(
 955+ return $j.getLineItem(
959956 gM( 'mwe-embedplayer-about-library' ),
960957 'info',
961958 function( ) {
962 - ctrlObj.displayMenuOverlay(
 959+ ctrlObj.displayMenuOverlay(
963960 ctrlObj.aboutPlayerLibrary()
964 - );
 961+ );
965962 $j( ctrlObj.embedPlayer ).trigger( 'aboutPlayerLibrary' );
966963 }
967964 );
968965 }
969966 },
970 -
971 - /**
972 - * Close a menu overlay
 967+
 968+ /**
 969+ * Close a menu overlay
973970 */
974971 closeMenuOverlay: function(){
975 - var _this = this;
 972+ var _this = this;
976973 var embedPlayer = this.embedPlayer;
977 - var $overlay = embedPlayer.$interface.find( '.overlay-win,.ui-widget-overlay,.ui-widget-shadow' );
978 -
 974+ var $overlay = embedPlayer.$interface.find( '.overlay-win,.ui-widget-overlay,.ui-widget-shadow' );
 975+
979976 this.displayOptionsMenuFlag = false;
980977 mw.log(' closeMenuOverlay: ' + this.displayOptionsMenuFlag);
981 -
 978+
982979 $overlay.fadeOut( "slow", function() {
983 - $overlay.remove();
 980+ $overlay.remove();
984981 } );
985 - // Show the big play button:
 982+ // Show the big play button:
986983 embedPlayer.$interface.find( '.play-btn-large' ).fadeIn( 'slow' );
987 -
988 -
 984+
 985+
989986 $j(embedPlayer).trigger( 'closeMenuOverlay' );
990 -
 987+
991988 return false; // onclick action return false
992989 },
993 -
994 - /**
995 - * Generic function to display custom HTML overlay
 990+
 991+ /**
 992+ * Generic function to display custom HTML overlay
996993 * on video.
997 - *
 994+ *
998995 * @param {String} overlayContent content to be displayed
999996 */
1000997 displayMenuOverlay: function( overlayContent ) {
@@ -1003,26 +1000,26 @@
10041001 // set the overlay display flag to true:
10051002 this.displayOptionsMenuFlag = true;
10061003 mw.log(" set displayOptionsMenuFlag:: " + this.displayOptionsMenuFlag);
1007 -
 1004+
10081005 if ( !this.supportedComponets[ 'overlays' ] ) {
10091006 embedPlayer.stop();
1010 - }
 1007+ }
10111008
1012 -
1013 - // Hide the big play button:
1014 - embedPlayer.$interface.find( '.play-btn-large' ).hide();
1015 -
1016 - // Check if overlay window is already present:
 1009+
 1010+ // Hide the big play button:
 1011+ embedPlayer.$interface.find( '.play-btn-large' ).hide();
 1012+
 1013+ // Check if overlay window is already present:
10171014 if ( embedPlayer.$interface.find( '.overlay-win' ).length != 0 ) {
1018 - //Update the content
 1015+ //Update the content
10191016 embedPlayer.$interface.find( '.overlay-content' ).html(
10201017 overlayContent
10211018 );
10221019 return ;
10231020 }
1024 -
 1021+
10251022 // Add an overlay
1026 - embedPlayer.$interface.append(
 1023+ embedPlayer.$interface.append(
10271024 $j('<div />')
10281025 .addClass( 'ui-widget-overlay' )
10291026 .css( {
@@ -1031,8 +1028,8 @@
10321029 'z-index' : 2
10331030 } )
10341031 );
1035 -
1036 - // Setup the close button
 1032+
 1033+ // Setup the close button
10371034 $closeButton = $j('<span />')
10381035 .addClass( 'ui-icon ui-icon-closethick' )
10391036 .css({
@@ -1045,190 +1042,187 @@
10461043 .click( function() {
10471044 _this.closeMenuOverlay();
10481045 } );
1049 -
 1046+
10501047 var overlayMenuCss = {
10511048 'height' : 200,
1052 - 'width' : 250,
 1049+ 'width' : 250,
10531050 'position' : 'absolute',
10541051 'left' : '10px',
10551052 'top': '15px',
10561053 'overflow' : 'auto',
10571054 'padding' : '4px',
10581055 'z-index' : 3
1059 - };
 1056+ };
10601057 $overlayMenu = $j('<div />')
10611058 .addClass( 'overlay-win ui-state-default ui-widget-header ui-corner-all' )
10621059 .css( overlayMenuCss )
10631060 .append(
10641061 $closeButton,
10651062 $j('<div />')
1066 - .addClass( 'overlay-content' )
 1063+ .addClass( 'overlay-content' )
10671064 .append( overlayContent )
10681065 );
1069 -
1070 - // Clone the overlay menu css:
 1066+
 1067+ // Clone the overlay menu css:
10711068 var shadowCss = jQuery.extend( true, {}, overlayMenuCss );
10721069 shadowCss['height' ] = 210;
10731070 shadowCss['width' ] = 260;
1074 - shadowCss[ 'z-index' ] = 2;
 1071+ shadowCss[ 'z-index' ] = 2;
10751072 $overlayShadow = $j( '<div />' )
10761073 .addClass('ui-widget-shadow ui-corner-all')
10771074 .css( shadowCss );
1078 -
1079 - // Append the overlay menu to the player interface
1080 - embedPlayer.$interface.prepend(
 1075+
 1076+ // Append the overlay menu to the player interface
 1077+ embedPlayer.$interface.prepend(
10811078 $overlayMenu,
10821079 $overlayShadow
10831080 )
10841081 .find( '.overlay-win' )
1085 - .fadeIn( "slow" );
1086 -
1087 - // trigger menu overlay display
 1082+ .fadeIn( "slow" );
 1083+
 1084+ // trigger menu overlay display
10881085 $j(embedPlayer).trigger( 'displayMenuOverlay' );
1089 -
 1086+
10901087 return false; // onclick action return false
1091 - },
 1088+ },
10921089 aboutPlayerLibrary: function(){
10931090 return $j( '<div />' )
10941091 .append(
10951092 $j( '<h3 />' )
1096 - .text(
1097 - gM('mwe-embedplayer-about-library')
 1093+ .text(
 1094+ gM('mwe-embedplayer-about-library')
10981095 )
10991096 ,
11001097 $j( '<span />')
11011098 .append(
1102 - gM('mwe-embedplayer-about-library-desc',
 1099+ gM('mwe-embedplayer-about-library-desc',
11031100 $j('<a />').attr({
11041101 'href' : mw.getConfig( 'EmbedPlayer.LibraryPage' ),
11051102 'target' : '_new'
11061103 })
11071104 )
1108 - )
 1105+ )
11091106 );
11101107 },
11111108 /**
11121109 * Get the "share" interface
1113 - *
 1110+ *
11141111 * TODO share should be enabled via <embed> tag usage to be compatible
11151112 * with sites social networking sites that allow <embed> tags but not js
1116 - *
 1113+ *
11171114 * @param {Object} $target Target jQuery object to set share html
11181115 */
11191116 getShare: function( ) {
11201117 var embedPlayer = this.embedPlayer;
1121 - var embed_code = embedPlayer.getEmbeddingHTML();
 1118+ var embed_code = embedPlayer.getEmbeddingHTML();
11221119 var _this = this;
1123 -
 1120+
11241121 var $shareInterface = $j('<div />');
1125 -
 1122+
11261123 $shareList = $j( '<ul />' );
1127 -
1128 - $shareList
1129 - .append(
 1124+
 1125+ $shareList
 1126+ .append(
11301127 $j('<li />')
1131 - .append(
1132 - $j('<a />')
1133 - .attr('href', '#')
1134 - .addClass( 'active' )
1135 - .text(
1136 - gM( 'mwe-embedplayer-embed_site_or_blog' )
1137 - )
1138 - )
1139 - );
1140 -
1141 - $shareInterface.append(
1142 - $j( '<h2 />' )
1143 - .text( gM( 'mwe-embedplayer-share_this_video' ) )
1144 - .append(
1145 - $shareList
1146 - )
1147 - );
1148 -
1149 - $shareInterface.append(
1150 -
1151 - $j('<span />')
1152 - .addClass( 'source_wrap' )
1153 - .html(
1154 - $j( '<textarea />' )
1155 - .html( embed_code )
1156 - .click( function() {
1157 - $j( this ).select();
1158 - })
1159 - ),
1160 -
1161 - $j('<br />'),
1162 - $j('<br />'),
1163 -
1164 - $j('<button />')
1165 - .addClass( 'ui-state-default ui-corner-all copycode' )
1166 - .text( gM( 'mwe-embedplayer-copy-code' ) )
1167 - .click(function() {
1168 - $shareInterface.find( 'textarea' ).focus().select();
 1128+ .append(
 1129+ $j('<a />')
 1130+ .attr('href', '#')
 1131+ .addClass( 'active' )
 1132+ .text(
 1133+ gM( 'mwe-embedplayer-embed_site_or_blog' )
 1134+ )
 1135+ )
 1136+ );
 1137+
 1138+ $shareInterface.append(
 1139+ $j( '<h2 />' )
 1140+ .text( gM( 'mwe-embedplayer-share_this_video' ) )
 1141+ .append(
 1142+ $shareList
 1143+ )
 1144+ );
 1145+
 1146+ $shareInterface.append(
 1147+
 1148+ $j( '<textarea />' )
 1149+ .attr( 'rows', 1 )
 1150+ .html( embed_code )
 1151+ .click( function() {
 1152+ $j( this ).select();
 1153+ }),
 1154+
 1155+ $j('<br />'),
 1156+ $j('<br />'),
 1157+
 1158+ $j('<button />')
 1159+ .addClass( 'ui-state-default ui-corner-all copycode' )
 1160+ .text( gM( 'mwe-embedplayer-copy-code' ) )
 1161+ .click(function() {
 1162+ $shareInterface.find( 'textarea' ).focus().select();
11691163 // Copy the text if supported:
11701164 if ( document.selection ) {
11711165 CopiedTxt = document.selection.createRange();
11721166 CopiedTxt.execCommand( "Copy" );
11731167 }
11741168 } )
1175 -
 1169+
11761170 );
11771171 return $shareInterface;
11781172 },
1179 -
 1173+
11801174 /**
11811175 * Shows the Player Select interface
1182 - *
 1176+ *
11831177 * @param {Object} $target jQuery target for output
11841178 */
1185 - getPlayerSelect: function( ) {
1186 - mw.log('ControlBuilder::getPlayerSelect: source:' +
 1179+ getPlayerSelect: function( ) {
 1180+ mw.log('ControlBuilder::getPlayerSelect: source:' +
11871181 this.embedPlayer.mediaElement.selectedSource.getSrc() +
1188 - ' player: ' + this.embedPlayer.selectedPlayer.id );
1189 -
 1182+ ' player: ' + this.embedPlayer.selectedPlayer.id );
 1183+
11901184 var embedPlayer = this.embedPlayer;
1191 -
 1185+
11921186 var _this = this;
1193 -
 1187+
11941188 $playerSelect = $j('<div />')
1195 - .append(
 1189+ .append(
11961190 $j( '<h2 />' )
1197 - .text( gM( 'mwe-embedplayer-choose_player' ) )
1198 - );
 1191+ .text( gM( 'mwe-embedplayer-choose_player' ) )
 1192+ );
11991193
12001194 $j.each( embedPlayer.mediaElement.getPlayableSources(), function( sourceId, source ) {
1201 -
1202 - var isPlayable = (typeof mw.EmbedTypes.players.defaultPlayer( source.getMIMEType() ) == 'object' );
1203 - var is_selected = ( source.getSrc() == embedPlayer.mediaElement.selectedSource.getSrc() );
1204 -
1205 - $playerSelect.append(
 1195+
 1196+ var isPlayable = (typeof mw.EmbedTypes.players.defaultPlayer( source.getMIMEType() ) == 'object' );
 1197+ var is_selected = ( source.getSrc() == embedPlayer.mediaElement.selectedSource.getSrc() );
 1198+
 1199+ $playerSelect.append(
12061200 $j( '<h2 />' )
12071201 .text( source.getTitle() )
12081202 );
1209 -
 1203+
12101204 if ( isPlayable ) {
12111205 $playerList = $j('<ul />');
12121206 // output the player select code:
1213 -
 1207+
12141208 var supportingPlayers = mw.EmbedTypes.players.getMIMETypePlayers( source.getMIMEType() );
12151209
1216 - for ( var i = 0; i < supportingPlayers.length ; i++ ) {
 1210+ for ( var i = 0; i < supportingPlayers.length ; i++ ) {
12171211
12181212 // Add link to select the player if not already selected )
1219 - if( embedPlayer.selectedPlayer.id == supportingPlayers[i].id && is_selected ) {
 1213+ if( embedPlayer.selectedPlayer.id == supportingPlayers[i].id && is_selected ) {
12201214 // Active player ( no link )
12211215 $playerLine = $j( '<span />' )
1222 - .text(
 1216+ .text(
12231217 supportingPlayers[i].getName()
12241218 )
1225 - .addClass( 'ui-state-highlight ui-corner-all' );
 1219+ .addClass( 'ui-state-highlight ui-corner-all' );
12261220 } else {
1227 - // Non active player add link to select:
 1221+ // Non active player add link to select:
12281222 $playerLine = $j( '<a />')
12291223 .attr({
12301224 'href' : '#',
12311225 'rel' : 'sel_source',
1232 - 'id' : 'sc_' + sourceId + '_' + supportingPlayers[i].id
 1226+ 'id' : 'sc_' + sourceId + '_' + supportingPlayers[i].id
12331227 })
12341228 .addClass( 'ui-corner-all')
12351229 .text( supportingPlayers[i].getName() )
@@ -1236,26 +1230,26 @@
12371231 var iparts = $j( this ).attr( 'id' ).replace(/sc_/ , '' ).split( '_' );
12381232 var sourceId = iparts[0];
12391233 var player_id = iparts[1];
1240 - mw.log( 'source id: ' + sourceId + ' player id: ' + player_id );
1241 -
 1234+ mw.log( 'source id: ' + sourceId + ' player id: ' + player_id );
 1235+
12421236 embedPlayer.controlBuilder.closeMenuOverlay();
1243 -
 1237+
12441238 // Close fullscreen if we are in fullscreen mode
12451239 if( _this.fullscreenMode ){
12461240 _this.restoreWindowPlayer();
12471241 }
1248 -
 1242+
12491243 embedPlayer.mediaElement.selectSource( sourceId );
12501244 var playableSources = embedPlayer.mediaElement.getPlayableSources();
1251 -
1252 - mw.EmbedTypes.players.setPlayerPreference(
 1245+
 1246+ mw.EmbedTypes.players.setPlayerPreference(
12531247 player_id,
1254 - playableSources[ sourceId ].getMIMEType()
 1248+ playableSources[ sourceId ].getMIMEType()
12551249 );
1256 -
 1250+
12571251 // Issue a stop
1258 - embedPlayer.stop();
1259 -
 1252+ embedPlayer.stop();
 1253+
12601254 // Don't follow the # link:
12611255 return false;
12621256 } )
@@ -1268,71 +1262,71 @@
12691263 }
12701264 );
12711265 }
1272 -
1273 - // Add the player line to the player list:
 1266+
 1267+ // Add the player line to the player list:
12741268 $playerList.append(
12751269 $j( '<li />' ).append(
12761270 $playerLine
12771271 )
12781272 );
12791273 }
1280 -
1281 - // Append the player list:
 1274+
 1275+ // Append the player list:
12821276 $playerSelect.append( $playerList );
1283 -
 1277+
12841278 } else {
1285 - // No player available:
1286 - $playerSelect.append( gM( 'mwe-embedplayer-no-player', source.getTitle() ) );
 1279+ // No player available:
 1280+ $playerSelect.append( gM( 'mwe-embedplayer-no-player', source.getTitle() ) );
12871281 }
12881282 } );
1289 -
 1283+
12901284 // Return the player select elements
1291 - return $playerSelect;
 1285+ return $playerSelect;
12921286 },
1293 -
 1287+
12941288 /**
1295 - * Show the text interface library and show the text interface near the player.
 1289+ * Show the text interface library and show the text interface near the player.
12961290 */
12971291 showTextInterface: function() {
12981292 var _this = this;
12991293 var embedPlayer = this.embedPlayer;
13001294 var loc = embedPlayer.$interface.find( '.rButton.timed-text' ).offset();
1301 - mw.log('showTextInterface::' + embedPlayer.id + ' t' + loc.top + ' r' + loc.right);
1302 -
1303 -
1304 - var $menu = $j( '#timedTextMenu_' + embedPlayer.id );
 1295+ mw.log('showTextInterface::' + embedPlayer.id + ' t' + loc.top + ' r' + loc.right);
 1296+
 1297+
 1298+ var $menu = $j( '#timedTextMenu_' + embedPlayer.id );
13051299 //This may be unnecessary .. we just need to show a spinner somewhere
13061300 if ( $menu.length != 0 ) {
1307 - // Hide show the menu:
 1301+ // Hide show the menu:
13081302 if( $menu.is( ':visible' ) ) {
13091303 $menu.hide( "fast" );
1310 - }else{
1311 - // move the menu to proper location
 1304+ }else{
 1305+ // move the menu to proper location
13121306 $menu.show("fast");
1313 - }
1314 - }else{
1315 - //Setup the menu:
1316 - $j('body').append(
1317 - $j('<div>')
1318 - .addClass('ui-widget ui-widget-content ui-corner-all')
1319 - .attr( 'id', 'timedTextMenu_' + embedPlayer.id )
 1307+ }
 1308+ }else{
 1309+ //Setup the menu:
 1310+ $j('body').append(
 1311+ $j('<div>')
 1312+ .addClass('ui-widget ui-widget-content ui-corner-all')
 1313+ .attr( 'id', 'timedTextMenu_' + embedPlayer.id )
13201314 .css( {
13211315 'position' : 'absolute',
13221316 'z-index' : 10,
13231317 'height' : '180px',
1324 - 'width' : '180px',
 1318+ 'width' : '180px',
13251319 'font-size' : '12px',
1326 - 'display' : 'none'
 1320+ 'display' : 'none'
13271321 } )
1328 -
1329 - );
 1322+
 1323+ );
13301324 // Load text interface ( if not already loaded )
1331 - mw.load( 'TimedText', function() {
1332 - $j( '#' + embedPlayer.id ).timedText( 'showMenu', '#timedTextMenu_' + embedPlayer.id );
1333 - });
1334 - }
 1325+ mw.load( 'TimedText', function() {
 1326+ $j( '#' + embedPlayer.id ).timedText( 'showMenu', '#timedTextMenu_' + embedPlayer.id );
 1327+ });
 1328+ }
13351329 },
1336 -
 1330+
13371331 /**
13381332 * Loads sources and calls showDownloadWithSources
13391333 * @param {Object} $target jQuery target to output to
@@ -1340,21 +1334,21 @@
13411335 showDownload: function( $target ) {
13421336 var _this = this;
13431337 var embedPlayer = this.embedPlayer;
1344 -
1345 - // Load the roe if available (to populate out download options:
 1338+
 1339+ // Load the roe if available (to populate out download options:
13461340 // mw.log('f:showDownload '+ this.roe + ' ' + this.mediaElement.addedROEData);
13471341 if ( embedPlayer.roe && embedPlayer.mediaElement.addedROEData == false ) {
13481342 $target.html( gM( 'mwe-loading_txt' ) );
13491343 embedPlayer.getMvJsonUrl( this.roe, function( data ) {
1350 - embedPlayer.mediaElement.addROE( data );
1351 - _this.showDownloadWithSources( $target );
 1344+ embedPlayer.mediaElement.addROE( data );
 1345+ _this.showDownloadWithSources( $target );
13521346 } );
1353 -
1354 - // Load additional text sources via apiTitleKey:
 1347+
 1348+ // Load additional text sources via apiTitleKey:
13551349 // @@ todo we should move this to timedText bindings
13561350 } else if( embedPlayer.apiTitleKey ) {
13571351 // Load text interface ( if not already loaded )
1358 - mw.load( 'TimedText', function() {
 1352+ mw.load( 'TimedText', function() {
13591353 embedPlayer.timedText.setupTextSources(function(){
13601354 _this.showDownloadWithSources( $target );
13611355 });
@@ -1363,7 +1357,7 @@
13641358 _this.showDownloadWithSources( $target );
13651359 }
13661360 },
1367 -
 1361+
13681362 /**
13691363 * Shows the download interface with sources loaded
13701364 * @param {Object} $target jQuery target to output to
@@ -1374,19 +1368,19 @@
13751369 var embedPlayer = this.embedPlayer;
13761370 // Empty the target:
13771371 $target.empty();
1378 -
 1372+
13791373 var $mediaList = $j( '<ul />' );
1380 - var $textList = $j( '<ul />' );
 1374+ var $textList = $j( '<ul />' );
13811375 $j.each( embedPlayer.mediaElement.getSources(), function( index, source ) {
1382 - if( source.getSrc() ) {
1383 - mw.log("showDownloadWithSources:: Add src: " + source.getTitle() );
 1376+ if( source.getSrc() ) {
 1377+ mw.log("showDownloadWithSources:: Add src: " + source.getTitle() );
13841378 var $dl_line = $j( '<li />').append(
1385 - $j('<a />')
 1379+ $j('<a />')
13861380 .attr( 'href', source.getSrc() )
1387 - .text( source.getTitle() )
1388 - );
1389 - // Add link to correct "bucket"
1390 -
 1381+ .text( source.getTitle() )
 1382+ );
 1383+ // Add link to correct "bucket"
 1384+
13911385 //Add link to time segment:
13921386 if ( source.getSrc().indexOf( '?t=' ) !== -1 ) {
13931387 $target.append( $dl_line );
@@ -1397,7 +1391,7 @@
13981392 // Add link to media list
13991393 $mediaList.append( $dl_line );
14001394 }
1401 -
 1395+
14021396 }
14031397 } );
14041398 if( $mediaList.find('li').length != 0 ) {
@@ -1407,17 +1401,17 @@
14081402 $mediaList
14091403 );
14101404 }
1411 -
 1405+
14121406 if( $textList.find('li').length != 0 ) {
14131407 $target.append(
14141408 $j('<h2 />')
14151409 .html( gM( 'mwe-embedplayer-download_text' ) ),
14161410 $textList
14171411 );
1418 - }
 1412+ }
14191413 },
1420 -
1421 -
 1414+
 1415+
14221416 /**
14231417 * Get component
14241418 *
@@ -1430,39 +1424,39 @@
14311425 return false;
14321426 }
14331427 },
1434 -
 1428+
14351429 /**
14361430 * Get a component height
1437 - *
 1431+ *
14381432 * @param {String} component_id Component key to grab height
14391433 * @return height or false if not set
14401434 */
14411435 getComponentHeight: function( component_id ) {
1442 - if ( this.components[ component_id ]
1443 - && this.components[ component_id ].h )
 1436+ if ( this.components[ component_id ]
 1437+ && this.components[ component_id ].h )
14441438 {
14451439 return this.components[ component_id ].h;
14461440 }
14471441 return false;
14481442 },
1449 -
 1443+
14501444 /**
14511445 * Get a component width
14521446 * @param {String} component_id Component key to grab width
14531447 * @return width or false if not set
14541448 */
14551449 getComponentWidth: function( component_id ){
1456 - if ( this.components[ component_id ]
1457 - && this.components[ component_id ].w )
 1450+ if ( this.components[ component_id ]
 1451+ && this.components[ component_id ].w )
14581452 {
14591453 return this.components[ component_id ].w;
14601454 }
14611455 return false;
14621456 },
1463 -
 1457+
14641458 /**
14651459 * Components Object
1466 - * Take in the embedPlayer and return some html for the given component.
 1460+ * Take in the embedPlayer and return some html for the given component.
14671461 *
14681462 * components can be overwritten by skin javascript
14691463 *
@@ -1471,15 +1465,15 @@
14721466 * 'w' The width of the component
14731467 * 'h' The height of the component ( if height is undefined the height of the control bar is used )
14741468 */
1475 - components: {
 1469+ components: {
14761470 /**
14771471 * The large play button in center of the player
14781472 */
14791473 'playButtonLarge': {
14801474 'w' : 130,
14811475 'h' : 96,
1482 - 'o' : function( ctrlObj ) {
1483 -
 1476+ 'o' : function( ctrlObj ) {
 1477+
14841478 return $j( '<div/>' )
14851479 .attr( {
14861480 'title' : gM( 'mwe-embedplayer-play_clip' ),
@@ -1494,31 +1488,31 @@
14951489 .buttonHover().click( function() {
14961490 ctrlObj.embedPlayer.play();
14971491 } );
1498 - }
 1492+ }
14991493 },
1500 -
 1494+
15011495 /**
15021496 * The Attribution button ( by default this is kaltura-icon
15031497 */
15041498 'attributionButton' : {
15051499 'w' : 28,
1506 - 'o' : function( ctrlObj ){
 1500+ 'o' : function( ctrlObj ){
15071501 var buttonConfig = mw.getConfig( 'EmbedPlayer.AttributionButton');
1508 -
 1502+
15091503 var $icon = $j('<span />')
15101504 .addClass( 'ui-icon' );
15111505 if( buttonConfig['class'] ){
15121506 $icon.addClass( buttonConfig['class'] );
1513 - }
 1507+ }
15141508 // Check for source ( by configuration convention this is a 16x16 image
15151509 if( buttonConfig.iconurl ){
1516 - $icon.append(
 1510+ $icon.append(
15171511 $j('<img />')
15181512 .css({'width': '16px', 'height': '16px'})
15191513 .attr('src', buttonConfig.iconurl )
15201514 );
15211515 }
1522 -
 1516+
15231517 return $j('<a />')
15241518 .attr({
15251519 'href': buttonConfig.href,
@@ -1532,13 +1526,13 @@
15331527 'top' : '9px',
15341528 'left' : '2px'
15351529 })
1536 - .append(
 1530+ .append(
15371531 $icon
15381532 )
1539 - );
 1533+ );
15401534 }
15411535 },
1542 -
 1536+
15431537 /**
15441538 * The options button, invokes display of the options menu
15451539 */
@@ -1546,39 +1540,39 @@
15471541 'w': 28,
15481542 'o': function( ctrlObj ) {
15491543 return $j( '<div />' )
1550 - .attr( 'title', gM( 'mwe-embedplayer-player_options' ) )
 1544+ .attr( 'title', gM( 'mwe-embedplayer-player_options' ) )
15511545 .addClass( 'ui-state-default ui-corner-all ui-icon_link rButton options-btn' )
1552 - .append(
 1546+ .append(
15531547 $j('<span />')
15541548 .addClass( 'ui-icon ui-icon-wrench' )
1555 - )
1556 - .buttonHover()
1557 - // Options binding:
 1549+ )
 1550+ .buttonHover()
 1551+ // Options binding:
15581552 .menu( {
15591553 'content' : ctrlObj.getOptionsMenu(),
1560 - 'zindex' : mw.getConfig( 'EmbedPlayer.fullScreenZIndex' ) + 1,
 1554+ 'zindex' : mw.getConfig( 'EmbedPlayer.fullScreenZIndex' ) + 1,
15611555 'positionOpts': {
1562 - 'directionV' : 'up',
 1556+ 'directionV' : 'up',
15631557 'offsetY' : 30,
15641558 'directionH' : 'left',
15651559 'offsetX' : -28
1566 - }
1567 - } );
 1560+ }
 1561+ } );
15681562 }
15691563 },
1570 -
 1564+
15711565 /**
15721566 * The fullscreen button for displaying the video fullscreen
15731567 */
15741568 'fullscreen': {
15751569 'w': 28,
15761570 'o': function( ctrlObj ) {
1577 -
1578 - // Setup "dobuleclick" fullscreen binding to embedPlayer
 1571+
 1572+ // Setup "dobuleclick" fullscreen binding to embedPlayer
15791573 $j( ctrlObj.embedPlayer ).unbind("dblclick").bind("dblclick", function(){
1580 - ctrlObj.embedPlayer.fullscreen();
1581 - });
1582 -
 1574+ ctrlObj.embedPlayer.fullscreen();
 1575+ });
 1576+
15831577 return $j( '<div />' )
15841578 .attr( 'title', gM( 'mwe-embedplayer-player_fullscreen' ) )
15851579 .addClass( "ui-state-default ui-corner-all ui-icon_link rButton fullscreen-btn" )
@@ -1593,8 +1587,8 @@
15941588 } );
15951589 }
15961590 },
1597 -
1598 -
 1591+
 1592+
15991593 /**
16001594 * The pause / play button
16011595 */
@@ -1604,18 +1598,18 @@
16051599 return $j( '<div />' )
16061600 .attr( 'title', gM( 'mwe-embedplayer-play_clip' ) )
16071601 .addClass ( "ui-state-default ui-corner-all ui-icon_link lButton play-btn" )
1608 - .append(
 1602+ .append(
16091603 $j( '<span />' )
16101604 .addClass( "ui-icon ui-icon-play" )
16111605 )
16121606 // Play / pause binding
16131607 .buttonHover()
16141608 .click( function() {
1615 - ctrlObj.embedPlayer.play();
 1609+ ctrlObj.embedPlayer.play();
16161610 });
16171611 }
16181612 },
1619 -
 1613+
16201614 /**
16211615 * The closed captions button
16221616 */
@@ -1625,19 +1619,19 @@
16261620 return $j( '<div />' )
16271621 .attr( 'title', gM( 'mwe-embedplayer-timed_text' ) )
16281622 .addClass( "ui-state-default ui-corner-all ui-icon_link rButton timed-text" )
1629 - .append(
 1623+ .append(
16301624 $j( '<span />' )
16311625 .addClass( "ui-icon ui-icon-comment" )
16321626 )
16331627 // Captions binding:
16341628 .buttonHover()
1635 - .click( function() {
 1629+ .click( function() {
16361630 ctrlObj.showTextInterface();
1637 - } );
 1631+ } );
16381632 }
16391633 },
1640 -
1641 - /**
 1634+
 1635+ /**
16421636 * The volume control interface html
16431637 */
16441638 'volumeControl': {
@@ -1646,42 +1640,42 @@
16471641 mw.log( 'PlayerControlBuilder::Set up volume control for: ' + ctrlObj.embedPlayer.id );
16481642 $volumeOut = $j( '<span />' );
16491643 if ( ctrlObj.volume_layout == 'horizontal' ) {
1650 - $volumeOut.append(
 1644+ $volumeOut.append(
16511645 $j( '<div />' )
16521646 .addClass( "ui-slider ui-slider-horizontal rButton volume-slider" )
16531647 );
16541648 }
1655 -
 1649+
16561650 // Add the volume control icon
1657 - $volumeOut.append(
 1651+ $volumeOut.append(
16581652 $j('<div />')
16591653 .attr( 'title', gM( 'mwe-embedplayer-volume_control' ) )
16601654 .addClass( "ui-state-default ui-corner-all ui-icon_link rButton volume_control" )
1661 - .append(
 1655+ .append(
16621656 $j( '<span />' )
16631657 .addClass( "ui-icon ui-icon-volume-on" )
16641658 )
1665 - );
 1659+ );
16661660 if ( ctrlObj.volume_layout == 'vertical' ) {
1667 - $volumeOut.find('.volume_control').append(
 1661+ $volumeOut.find('.volume_control').append(
16681662 $j( '<div />' )
16691663 .css( {
1670 - 'position' : 'absolute',
 1664+ 'position' : 'absolute',
16711665 'left' : '0px'
16721666 })
16731667 .hide()
16741668 .addClass( "vol_container ui-corner-all" )
1675 - .append(
 1669+ .append(
16761670 $j( '<div />' )
16771671 .addClass ( "volume-slider" )
16781672 )
16791673 );
1680 - }
1681 - //Return the inner html
 1674+ }
 1675+ //Return the inner html
16821676 return $volumeOut.html();
16831677 }
16841678 },
1685 -
 1679+
16861680 /*
16871681 * The time display area
16881682 */
@@ -1690,12 +1684,12 @@
16911685 'o' : function( ctrlObj ) {
16921686 return $j( '<div />' )
16931687 .addClass( "ui-widget time-disp" )
1694 - .append(
 1688+ .append(
16951689 ctrlObj.embedPlayer.getTimeRange()
16961690 );
16971691 }
16981692 },
1699 -
 1693+
17001694 /**
17011695 * The playhead component
17021696 */
@@ -1706,11 +1700,11 @@
17071701 var _this = this;
17081702 var $playHead = $j( '<div />' )
17091703 .addClass ( "play_head" )
1710 - .css({
 1704+ .css({
17111705 "position" : 'absolute',
17121706 "left" : '33px',
1713 - "right" : ( ( embedPlayer.getPlayerWidth() - ctrlObj.available_width ) - 33) + 'px'
1714 - })
 1707+ "right" : ( ( embedPlayer.getPlayerWidth() - ctrlObj.available_width ) - 33) + 'px'
 1708+ })
17151709 // Playhead binding
17161710 .slider( {
17171711 range: "min",
@@ -1728,7 +1722,7 @@
17291723 slide: function( event, ui ) {
17301724 var perc = ui.value / 1000;
17311725 embedPlayer.jump_time = mw.seconds2npt( parseFloat( parseFloat( embedPlayer.getDuration() ) * perc ) + embedPlayer.start_time_sec );
1732 - // mw.log('perc:' + perc + ' * ' + embedPlayer.getDuration() + ' jt:'+ this.jump_time);
 1726+ // mw.log('perc:' + perc + ' * ' + embedPlayer.getDuration() + ' jt:'+ this.jump_time);
17331727 if ( _this.longTimeDisp ) {
17341728 ctrlObj.setStatus( gM( 'mwe-embedplayer-seek_to', embedPlayer.jump_time ) );
17351729 } else {
@@ -1740,12 +1734,12 @@
17411735 }
17421736 },
17431737 change:function( event, ui ) {
1744 - // Only run the onChange event if done by a user slide
 1738+ // Only run the onChange event if done by a user slide
17451739 // (otherwise it runs times it should not)
17461740 if ( embedPlayer.userSlide ) {
17471741 embedPlayer.userSlide = false;
17481742 embedPlayer.seeking = true;
1749 -
 1743+
17501744 var perc = ui.value / 1000;
17511745 // set seek time (in case we have to do a url seek)
17521746 embedPlayer.seek_time_sec = mw.npt2seconds( embedPlayer.jump_time, true );
@@ -1755,19 +1749,19 @@
17561750 }
17571751 }
17581752 } );
1759 -
 1753+
17601754 // Up the z-index of the default status indicator:
17611755 $playHead.find( '.ui-slider-handle' ).css( 'z-index', 4 );
17621756 $playHead.find( '.ui-slider-range' ).addClass( 'ui-corner-all' ).css( 'z-index', 2 );
1763 -
1764 - // Add buffer html:
1765 - $playHead.append(
 1757+
 1758+ // Add buffer html:
 1759+ $playHead.append(
17661760 $j('<div />')
17671761 .addClass( "ui-slider-range ui-slider-range-min ui-widget-header")
17681762 .addClass( "ui-state-highlight ui-corner-all mw_buffer")
17691763 );
1770 -
1771 - return $playHead;
 1764+
 1765+ return $playHead;
17721766 }
17731767 }
17741768 }
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/skins/mvpcf/mw.style.PlayerSkinMvpcf.css
@@ -1,5 +1,5 @@
22 /**
3 - * reference player skin
 3+ * reference player skin
44 */
55
66
@@ -18,8 +18,8 @@
1919 height: 305px;
2020 }
2121 .mv-player .control-bar {
22 - height: 29px;
23 - z-index: 2;
 22+ height: 29px;
 23+ z-index: 2;
2424 }
2525 .mv-player .controlInnerSmall {
2626 /* width: 430px;*/
@@ -55,7 +55,7 @@
5656 width: 22px;
5757 height: 29px;
5858 padding: 0 0 0 0;
59 -
 59+
6060 }
6161
6262 .mv-player .vol_container{
@@ -72,18 +72,18 @@
7373 top:-77px;
7474 }
7575 .mv-player .vol_container .volume-slider{
76 - margin-top:5px;
 76+ margin-top:5px;
7777 height:65px;
7878 width:10px;
7979 margin-left: auto ;
80 - margin-right: auto ;
 80+ margin-right: auto ;
8181 }
8282 .mv-player .vol_container .ui-slider-handle{
8383 cursor : pointer;
8484 width:10px;
85 - height:10px;
 85+ height:10px;
8686 position:absolute;
87 - left:-1px;
 87+ left:-1px;
8888 }
8989
9090 .mv-player .time-disp {
@@ -99,23 +99,23 @@
100100
101101 .mv-player .play_head{
102102 float: left;
103 - display: inline;
 103+ display: inline;
104104 height: 10px;
105105 margin-left:8px;
106106 margin-top:10px;
107 - position:relative;
 107+ position:relative;
108108 }
109109
110110 .mv-player .play_head .ui-slider-handle{
111111 width:10px;
112112 height:15px;
113113 margin-left:-5px;
114 - margin-top: -0px;
 114+ margin-top: -0px;
115115 z-index: 2;
116116 }
117117
118118 .mv-player .inOutSlider .ui-slider-handle{
119 - width:8px;
 119+ width:8px;
120120 cusror: move;
121121 }
122122
@@ -152,7 +152,7 @@
153153
154154 .mv-player .overlay-win{
155155 font-family : arial,sans-serif;
156 - font-size : 85%;
 156+ font-size : 85%;
157157 }
158158 .mv-player .overlay-win a{
159159 text-decoration: none;
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/EmbedPlayer.resources.php
@@ -25,4 +25,4 @@
2626
2727 "mw.PlayerSkinMvpcf" => array( 'scripts'=> "skins/mvpcf/mw.PlayerSkinMvpcf.js"),
2828 "mw.style.PlayerSkinMvpcf" => array( 'scripts'=> "skins/mvpcf/mw.style.PlayerSkinMvpcf.css"),
29 -);
\ No newline at end of file
 29+);
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerJava.js
@@ -14,8 +14,8 @@
1515
1616 // Instance name:
1717 instanceOf: 'Java',
18 -
19 - // Supported feature set of the cortado applet:
 18+
 19+ // Supported feature set of the cortado applet:
2020 supports: {
2121 'playHead' : true,
2222 'pause' : true,
@@ -24,24 +24,24 @@
2525 'timeDisplay' : true,
2626 'volumeControl' : false
2727 },
28 -
 28+
2929 /**
3030 * Output the the embed html
3131 */
3232 doEmbedHTML: function () {
3333 var _this = this;
3434 mw.log( "java play url:" + this.getSrc( this.seek_time_sec ) );
35 -
36 - var applet_loc = this.getAppletLocation();
37 -
 35+
 36+ var applet_loc = this.getAppletLocation();
 37+
3838 mw.log('Applet location: ' + applet_loc );
3939 mw.log('Play media: ' + this.getSrc() );
40 -
 40+
4141 // load directly in the page..
4242 // (media must be on the same server or applet must be signed)
4343 var appletCode = '' +
4444 '<applet id="' + this.pid + '" code="com.fluendo.player.Cortado.class" ' +
45 - 'archive="' + applet_loc + '" width="' + parseInt( this.getWidth() ) + '" ' +
 45+ 'archive="' + applet_loc + '" width="' + parseInt( this.getWidth() ) + '" ' +
4646 'height="' + parseInt( this.getHeight() ) + '"> ' + "\n" +
4747 '<param name="url" value="' + this.getSrc() + '" /> ' + "\n" +
4848 '<param name="local" value="false"/>' + "\n" +
@@ -50,19 +50,19 @@
5151 '<param name="showStatus" value="hide" />' + "\n" +
5252 '<param name="audio" value="true" />' + "\n" +
5353 '<param name="seekable" value="true" />' + "\n";
54 -
55 - // Add the duration attribute if set:
 54+
 55+ // Add the duration attribute if set:
5656 if( this.getDuration() ){
57 - appletCode += '<param name="duration" value="' + parseFloat( this.getDuration() ) + '" />' + "\n";
 57+ appletCode += '<param name="duration" value="' + parseFloat( this.getDuration() ) + '" />' + "\n";
5858 }
59 -
 59+
6060 appletCode += '<param name="bufferSize" value="4096" />' + "\n" +
6161 '</applet>';
62 -
 62+
6363 $j( this ).html( appletCode );
64 -
 64+
6565 // Wrap it in an iframe to avoid hanging the event thread in FF 2/3 and similar
66 - // NOTE: This breaks reference to the applet so disabled for now:
 66+ // NOTE: This breaks reference to the applet so disabled for now:
6767 /*if ( $j.browser.mozilla ) {
6868 var iframe = document.createElement( 'iframe' );
6969 iframe.setAttribute( 'width', this.getWidth() );
@@ -72,103 +72,103 @@
7373 iframe.setAttribute( 'marginWidth', 0 );
7474 iframe.setAttribute( 'marginHeight', 0 );
7575 iframe.setAttribute( 'id', 'cframe_' + this.id )
76 -
77 - // Append the iframe to the embed object:
 76+
 77+ // Append the iframe to the embed object:
7878 $j( this ).html( iframe );
79 -
80 - // Write out the iframe content:
 79+
 80+ // Write out the iframe content:
8181 var newDoc = iframe.contentDocument;
8282 newDoc.open();
8383 newDoc.write( '<html><body>' + appletCode + '</body></html>' );
8484 // spurious error in some versions of FF, no workaround known
85 - newDoc.close();
 85+ newDoc.close();
8686 } else {
8787 $j( this ).html( appletCode );
88 - //}
89 - */
90 -
91 - // Start the monitor:
 88+ //}
 89+ */
 90+
 91+ // Start the monitor:
9292 _this.monitor();
9393 },
94 -
 94+
9595 /**
9696 * Get the applet location
9797 */
9898 getAppletLocation: function() {
9999 var mediaSrc = this.getSrc();
100100 var applet_loc = false;
101 - if (
102 - !mw.isLocalDomain( mediaSrc )
103 - ||
104 - !mw.isLocalDomain( mw.getMwEmbedPath()
 101+ if (
 102+ !mw.isLocalDomain( mediaSrc )
105103 ||
106 - mw.getConfig( 'relativeCortadoAppletPath' ) === false )
 104+ !mw.isLocalDomain( mw.getMwEmbedPath()
 105+ ||
 106+ mw.getConfig( 'relativeCortadoAppletPath' ) === false )
107107 ){
108108 if ( window.cortadoDomainLocations[ mw.parseUri( mediaSrc ).host ] ) {
109 - applet_loc = window.cortadoDomainLocations[ mw.parseUri( mediaSrc ).host ];
 109+ applet_loc = window.cortadoDomainLocations[ mw.parseUri( mediaSrc ).host ];
110110 } else {
111 - applet_loc = 'http://theora.org/cortado.jar';
 111+ applet_loc = 'http://theora.org/cortado.jar';
112112 }
113113 } else {
114 - // Get the local relative cortado applet location:
115 - applet_loc = mw.getConfig( 'relativeCortadoAppletPath' );
 114+ // Get the local relative cortado applet location:
 115+ applet_loc = mw.getConfig( 'relativeCortadoAppletPath' );
116116 }
117117 return applet_loc;
118118 },
119 -
 119+
120120 /**
121121 * Get the embed player time
122122 */
123123 getPlayerElementTime: function() {
124 - this.getPlayerElement();
125 - var currentTime = 0;
 124+ this.getPlayerElement();
 125+ var currentTime = 0;
126126 if ( this.playerElement ) {
127127 try {
128 - // java reads ogg media time.. so no need to add the start or seek offset:
129 - //mw.log(' ct: ' + this.playerElement.getPlayPosition() + ' ' + this.supportsURLTimeEncoding());
130 -
131 - currentTime = this.playerElement.currentTime;
132 - if ( this.currentTime < 0 ) {
133 - mw.log( 'pp:' + this.currentTime );
134 - // Probably reached clip ( should fire ondone event instead )
 128+ // java reads ogg media time.. so no need to add the start or seek offset:
 129+ //mw.log(' ct: ' + this.playerElement.getPlayPosition() + ' ' + this.supportsURLTimeEncoding());
 130+
 131+ currentTime = this.playerElement.currentTime;
 132+ if ( this.currentTime < 0 ) {
 133+ mw.log( 'pp:' + this.currentTime );
 134+ // Probably reached clip ( should fire ondone event instead )
135135 this.onClipDone();
136 - }
 136+ }
137137 } catch ( e ) {
138 - mw.log( 'could not get time from jPlayer: ' + e );
 138+ mw.log( 'could not get time from jPlayer: ' + e );
139139 }
140140 }else{
141141 mw.log(" could not find playerElement " );
142142 }
143143 return currentTime;
144144 },
145 -
 145+
146146 /**
147 - * Seek in the ogg stream
148 - * ( Cortado seek does not seem to work very well )
 147+ * Seek in the ogg stream
 148+ * ( Cortado seek does not seem to work very well )
149149 * @param {Float} percentage Percentage to seek into the stream
150150 */
151 - doSeek: function( percentage ) {
152 - mw.log( 'java:seek:p: ' + percentage + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
 151+ doSeek: function( percentage ) {
 152+ mw.log( 'java:seek:p: ' + percentage + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
153153 this.getPlayerElement();
154 -
 154+
155155 if ( this.supportsURLTimeEncoding() ) {
156 - this.parent_doSeek( percentage );
 156+ this.parent_doSeek( percentage );
157157 } else if ( this.playerElement ) {
158 - // do a (generally broken) local seek:
159 - mw.log( "Cortado seek is not very accurate :: doSeek::" + ( percentage * parseFloat( this.getDuration() ) ) );
160 - this.playerElement.currentTime = ( percentage * parseFloat( this.getDuration() ) );
 158+ // do a (generally broken) local seek:
 159+ mw.log( "Cortado seek is not very accurate :: doSeek::" + ( percentage * parseFloat( this.getDuration() ) ) );
 160+ this.playerElement.currentTime = ( percentage * parseFloat( this.getDuration() ) );
161161 } else {
162 - this.doPlayThenSeek( percentage );
 162+ this.doPlayThenSeek( percentage );
163163 }
164 -
 164+
165165 // Run the onSeeking interface update
166166 this.controlBuilder.onSeek();
167167 },
168 -
 168+
169169 /**
170170 * Issue a play request then seek to a percentage point in the stream
171171 * @param {Float} percentage Percentage to seek into the stream
172 - */
 172+ */
173173 doPlayThenSeek: function( percentage ) {
174174 mw.log( 'doPlayThenSeek' );
175175 var _this = this;
@@ -176,11 +176,11 @@
177177 var rfsCount = 0;
178178 var readyForSeek = function() {
179179 _this.getPlayerElement();
180 - // if we have .jre ~in theory~ we can seek (but probably not)
 180+ // if we have .jre ~in theory~ we can seek (but probably not)
181181 if ( _this.playerElement ) {
182182 _this.doSeek( perc );
183183 } else {
184 - // try to get player for 10 seconds:
 184+ // try to get player for 10 seconds:
185185 if ( rfsCount < 200 ) {
186186 setTimeout( readyForSeek, 50 );
187187 rfsCount++;
@@ -191,9 +191,9 @@
192192 }
193193 readyForSeek();
194194 },
195 -
 195+
196196 /**
197 - * Update the playerElement instance with a pointer to the embed object
 197+ * Update the playerElement instance with a pointer to the embed object
198198 */
199199 getPlayerElement: function() {
200200 if( !$j( '#' + this.pid ).length ) {
@@ -202,15 +202,15 @@
203203 //mw.log( 'getPlayerElement::' + this.pid );
204204 this.playerElement = $j( '#' + this.pid ).get( 0 );
205205 //this.playerElement = document.applets[ 0 ];
206 - // NOTE we are currently not using the iframe embed method:
 206+ // NOTE we are currently not using the iframe embed method:
207207 //if ( $j.browser.mozilla ) {
208 - // this.playerElement = $j('#cframe_' + this.id).contents().find( '#' + this.pid );
 208+ // this.playerElement = $j('#cframe_' + this.id).contents().find( '#' + this.pid );
209209 //} else {
210210 // this.playerElement = $j( '#' + this.pid ).get( 0 );
211211 //}
212212 return this.playerElement;
213 - },
214 -
 213+ },
 214+
215215 /**
216216 * Issue the doPlay request to the playerElement
217217 * calls parent_play to update interface
@@ -226,16 +226,16 @@
227227 }
228228 }
229229 },
230 -
 230+
231231 /**
232232 * Pause playback
233233 * calls parent_pause to update interface
234 - */
 234+ */
235235 pause: function() {
236236 this.getPlayerElement();
237237 // Update the interface
238238 this.parent_pause();
239 - // Call the pause function if it exists:
 239+ // Call the pause function if it exists:
240240 if ( this.playerElement ) {
241241 this.playerElement.pause();
242242 }
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerHtml.js
@@ -1,19 +1,19 @@
22 /*
33 * Used to embed HTML as a movie clip
44 * for use with mv_playlist SMIL additions
5 - *
6 - * NOTE: will be deprecated
 5+ *
 6+ * NOTE: will be deprecated
77 */
88 var pcHtmlEmbedDefaults = {
9 - // default duration of 4 seconds
10 - 'dur':4
 9+ // default duration of 4 seconds
 10+ 'dur':4
1111 }
1212
1313 mw.EmbedPlayerHtml = {
14 -
15 - // Instance name:
16 - instanceOf: 'Html',
1714
 15+ // Instance name:
 16+ instanceOf: 'Html',
 17+
1818 // List of supported features
1919 supports: {
2020 'playHead':true,
@@ -24,27 +24,27 @@
2525
2626 'overlays':true
2727 },
28 -
 28+
2929 // If the player is "ready to play"
3030 ready_to_play:true,
31 -
 31+
3232 // Pause time used to track player time between pauses
3333 pauseTime:0,
34 -
 34+
3535 // currentTime updated via internal clockStartTime var
3636 currentTime:0,
37 -
 37+
3838 // StartOffset support seeking into the virtual player
3939 startOffset:0,
40 -
 40+
4141 // The local clock used to emulate playback time
4242 clockStartTime: 0,
43 -
 43+
4444 /**
4545 * Play function starts the v
4646 */
4747 play: function() {
48 - mw.log(" parent: " + this.parent_play);
 48+ mw.log(" parent: " + this.parent_play);
4949 // call the parent
5050 this.parent_play();
5151
@@ -55,27 +55,27 @@
5656 // Start up monitor:
5757 this.monitor();
5858 },
59 -
 59+
6060 /**
6161 * Stops the playback
6262 */
6363 stop:function() {
6464 this.currentTime = 0;
65 - this.pause();
 65+ this.pause();
6666 },
67 -
 67+
6868 /**
69 - * Preserves the pause time across for timed playback
 69+ * Preserves the pause time across for timed playback
7070 */
7171 pause:function() {
7272 mw.log( 'f:pause: htmlEmbedWrapper' );
7373 var ct = new Date();
7474 this.pauseTime = this.currentTime;
7575 mw.log( 'pause time: ' + this.pauseTime );
76 -
 76+
7777 window.clearInterval( this.monitorTimerId );
7878 },
79 -
 79+
8080 /**
8181 * Seeks to a given percent and updates the pauseTime
8282 *
@@ -85,9 +85,9 @@
8686 this.pauseTime = perc * this.getDuration();
8787 this.play();
8888 },
89 -
90 - /**
91 - * Sets the current Time
 89+
 90+ /**
 91+ * Sets the current Time
9292 *
9393 * @param {Float} perc Percentage to seek into the virtual player
9494 * @param {Function} callback Function called once time has been updated
@@ -97,20 +97,20 @@
9898 if( callback )
9999 callback();
100100 },
101 -
 101+
102102 /**
103103 * Get the embed player time
104104 */
105105 getPlayerElementTime: function() {
106 - //mw.log('html:monitor: '+ this.currentTime);
 106+ //mw.log('html:monitor: '+ this.currentTime);
107107 var ct = new Date();
108 - var currentTime = ( ( ct.getTime() - this.clockStartTime ) / 1000 ) + this.pauseTime;
 108+ var currentTime = ( ( ct.getTime() - this.clockStartTime ) / 1000 ) + this.pauseTime;
109109 return currentTime;
110110 },
111 -
 111+
112112 /**
113113 * Minimal media_element emulation:
114 - */
 114+ */
115115 media_element: {
116116 autoSelectSource:function() {
117117 return true;
@@ -125,55 +125,55 @@
126126 return false;
127127 }
128128 },
129 -
130 - /**
131 - * HtmlEmbed supports virtual instances without inheriting the embedPlayer
 129+
 130+ /**
 131+ * HtmlEmbed supports virtual instances without inheriting the embedPlayer
132132 */
133133 inheritEmbedPlayer: function() {
134134 return true;
135135 },
136 -
 136+
137137 /**
138138 * Render out a Thumbnail representation for use in the sequencer
139139 *
140140 * @param {Object} options Thumbnail options
141 - */
 141+ */
142142 renderTimelineThumbnail:function( options ) {
143143 mw.log( "HTMLembed req w, height: " + options.width + ' ' + options.height );
144 - // generate a scaled down version _that_ we can clone if necessary
 144+ // generate a scaled down version _that_ we can clone if necessary
145145 // add a not visible container to the body:
146146 var do_refresh = ( typeof options['refresh'] != 'undefined' ) ? true:false;
147147
148 - var thumb_render_id = this.id + '_thumb_render_' + options.height;
149 - if ( $j( '#' + thumb_render_id ).length == 0 || do_refresh ) {
150 -
 148+ var thumb_render_id = this.id + '_thumb_render_' + options.height;
 149+ if ( $j( '#' + thumb_render_id ).length == 0 || do_refresh ) {
 150+
151151 // Set the font scale down percentage: (kind of arbitrary)
152152 var scale_perc = options.width / this.pc.pp.width;
153 -
 153+
154154 mw.log( 'scale_perc:' + options.width + ' / ' + $j( this ).width() + ' = ' + scale_perc );
155 -
 155+
156156 // Min scale font percent of 70 (overflow is hidden)
157 - var font_perc = ( Math.round( scale_perc * 100 ) < 80 ) ? 80 : Math.round( scale_perc * 100 );
 157+ var font_perc = ( Math.round( scale_perc * 100 ) < 80 ) ? 80 : Math.round( scale_perc * 100 );
158158 var thumb_class = ( typeof options['thumb_class'] != 'undefined' ) ? options['thumb_class'] : '';
159159 $j( 'body' ).append( '<div id="' + thumb_render_id + '" style="display:none">' +
160160 '<div class="' + thumb_class + '" ' +
161161 'style="width:' + options.width + 'px;height:' + options.height + 'px;" >' +
162162 this.getThumbnailHTML( {
163 - 'width': options.width,
 163+ 'width': options.width,
164164 'height': options.height
165165 } ) +
166166 '</div>' +
167167 '</div>'
168 - );
169 -
 168+ );
 169+
170170 // Scale down the fonts:
171171 $j( '#' + thumb_render_id + ' *' ).filter( 'span,div,p,h,h1,h2,h3,h4,h5,h6' ).css( 'font-size', font_perc + '%' )
172 -
 172+
173173 // Replace out links:
174174 $j( '#' + thumb_render_id + ' a' ).each( function() {
175175 $j( this ).replaceWith( "<span>" + $j( this ).html() + "</span>" );
176176 } );
177 -
 177+
178178 // Scale images that have width or height:
179179 $j( '#' + thumb_render_id + ' img' ).filter( '[width]' ).each( function() {
180180 $j( this ).attr( {
@@ -187,34 +187,34 @@
188188 },
189189 /*
190190 * Updates the thumb time
191 - * (does nothings since we display a single frame rendered html page)
 191+ * (does nothings since we display a single frame rendered html page)
192192 *
193 - * @param {Float} float_time Ignored
 193+ * @param {Float} float_time Ignored
194194 */
195195 updateThumbTime:function( float_time ) {
196196 return ;
197197 },
198 -
 198+
199199 /**
200200 * Get the "embed" html for the html player
201201 */
202202 doEmbedHTML: function() {
203203 mw.log( 'f:html:doEmbedHTML: ' + this.id );
204 - // set up the css for our parent div:
 204+ // set up the css for our parent div:
205205 $j( this ).css( {
206206 'width':this.pc.pp.width,
207207 'height':this.pc.pp.height,
208208 'overflow':"hidden"
209209 } );
210 - // @@todo support more smil animation layout stuff:
 210+ // @@todo support more smil animation layout stuff:
211211
212212 // wrap output in videoPlayer_ div:
213213 $j( this ).html( this.getThumbnailHTML() );
214214 },
215 -
 215+
216216 /**
217217 * Get the ThumbnailHTML
218 - * ThumbnailHTML is used for both the "paused and playing states of the htmlEmbed player
 218+ * ThumbnailHTML is used for both the "paused and playing states of the htmlEmbed player
219219 */
220220 getThumbnailHTML: function( opt ) {
221221 var out = '';
@@ -223,7 +223,7 @@
224224 var height = ( opt.height ) ? opt.height:this.pc.pp.height;
225225 var width = ( opt.width ) ? opt.width: this.pc.pp.width;
226226 mw.log( '1req ' + opt.height + ' but got: ' + height );
227 - if ( this.pc.type == 'image/jpeg' || this.pc.type == 'image/png' ) {
 227+ if ( this.pc.type == 'image/jpeg' || this.pc.type == 'image/png' ) {
228228 mw.log( 'should put src: ' + this.pc.src );
229229 out = '<img style="width:' + width + 'px;height:' + height + 'px" src="' + this.pc.src + '">';
230230 } else {
@@ -236,7 +236,7 @@
237237 $j( this ).css( 'background', '#fff');
238238 $j( this ).html( this.getThumbnailHTML() );
239239 },
240 -
 240+
241241 /**
242242 * re-show the Thumbnail
243243 */
@@ -244,7 +244,7 @@
245245 mw.log( 'htmlEmbed:showThumbnail()' );
246246 this.getEmbedHTML();
247247 },
248 -
 248+
249249 /**
250250 * Get the media duration
251251 */
@@ -254,22 +254,22 @@
255255 this.duration = this.pc.dur;
256256 }else if( pcHtmlEmbedDefaults.dur ) {
257257 this.duration = pcHtmlEmbedDefaults.dur ;
258 - }
259 - }
260 - return this.duration;
 258+ }
 259+ }
 260+ return this.duration;
261261 },
262 -
 262+
263263 /**
264 - * Updates the Video time
 264+ * Updates the Video time
265265 *
266266 * @param {String} start_npt Start time for update
267 - * @param {String} end_npt End time for update
 267+ * @param {String} end_npt End time for update
268268 */
269269 updateVideoTime:function( start_npt, end_npt ) {
270270 // since we don't really have timeline for html elements just take the delta and set it as the duration
271271 this.pc.dur = mw.npt2seconds( end_ntp ) - mw.npt2seconds( start_ntp );
272272 },
273 -
 273+
274274 /**
275275 * Local implementation of swapPlayerElement
276276 */
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerVlc.js
@@ -5,36 +5,36 @@
66 */
77 mw.EmbedPlayerVlc = {
88
9 - //Instance Name:
 9+ //Instance Name:
1010 instanceOf : 'Vlc',
11 -
12 - //What the vlc player / plug-in supports:
13 - supports : {
 11+
 12+ //What the vlc player / plug-in supports:
 13+ supports : {
1414 'playHead':true,
1515 'pause':true,
1616 'stop':true,
1717 'fullscreen':true,
1818 'timeDisplay':true,
1919 'volumeControl':true,
20 -
 20+
2121 'playlist_driver':true, // if the object supports playlist functions
2222 'overlay':false
2323 },
24 -
 24+
2525 // The previous state of the player instance
2626 prevState : 0,
27 -
 27+
2828 // Counter for waiting for vlc embed to be ready
2929 waitForVlcCount:0,
30 -
 30+
3131 // Store the current play time for vlc
3232 vlcCurrentTime: 0,
33 -
 33+
3434 /**
3535 * Get embed HTML
3636 */
3737 doEmbedHTML: function() {
38 - var _this = this;
 38+ var _this = this;
3939 $j( this ).html(
4040 '<object classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921" ' +
4141 'codebase="http://downloads.videolan.org/pub/videolan/vlc/latest/win32/axvlc.cab#Version=0,8,6,0" ' +
@@ -57,21 +57,21 @@
5858 /*
5959 $j( this ).html(
6060 '<embed type="application/x-vlc-plugin" pluginspage="http://www.videolan.org" version="VideoLAN.VLCPlugin.2" '+
61 - 'width="' + this.width +'" ' +
62 - 'height="' + this.height + '" ' +
63 - 'id="' + this.pid + '"> ' +
 61+ 'width="' + this.width +'" ' +
 62+ 'height="' + this.height + '" ' +
 63+ 'id="' + this.pid + '"> ' +
6464 '</embed>'
6565 );*/
66 -
67 -
68 - // give VLC 150ms to initialize before we start playback
 66+
 67+
 68+ // give VLC 150ms to initialize before we start playback
6969 // @@todo should be able to do this as an ready event
7070 this.waitForVlcCount = 0;
7171 setTimeout( function() {
7272 _this.postEmbedJS();
7373 }, 150 );
74 - },
75 -
 74+ },
 75+
7676 /**
7777 * Javascript to run post vlc embedding
7878 * Inserts the requested src to the embed instance
@@ -79,16 +79,16 @@
8080 postEmbedJS: function() {
8181 var _this = this;
8282 // load a pointer to the vlc into the object (this.playerElement)
83 - this.getPlayerElement();
84 - if ( this.playerElement && this.playerElement.playlist) {
85 - // manipulate the dom object to make sure vlc has the correct size:
 83+ this.getPlayerElement();
 84+ if ( this.playerElement && this.playerElement.playlist) {
 85+ // manipulate the dom object to make sure vlc has the correct size:
8686 this.playerElement.style.width = this.getWidth();
8787 this.playerElement.style.height = this.getHeight();
8888 this.playerElement.playlist.items.clear();
89 -
90 - // VLC likes absolute urls:
 89+
 90+ // VLC likes absolute urls:
9191 var src = mw.absoluteUrl( this.getSrc() ) ;
92 -
 92+
9393 // @@todo if client supports seeking no need to send seek_offset to URI
9494 mw.log( 'vlc play::' + src );
9595 var itemId = this.playerElement.playlist.add( src );
@@ -97,7 +97,7 @@
9898 this.playerElement.playlist.playItem( itemId );
9999 } else {
100100 mw.log( "error:cannot play at the moment !" );
101 - }
 101+ }
102102 setTimeout( function() {
103103 _this.monitor();
104104 }, 100 );
@@ -113,10 +113,10 @@
114114 }
115115 }
116116 },
117 -
118 - /**
 117+
 118+ /**
119119 * Handles seek requests based on temporal media source type support
120 - *
 120+ *
121121 * @param {Float} percent Seek to this percent of the stream
122122 */
123123 doSeek : function( percent ) {
@@ -136,7 +136,7 @@
137137 }
138138 this.parent_monitor();
139139 },
140 -
 140+
141141 /**
142142 * Issues a play request then seeks to a given time
143143 *
@@ -150,11 +150,11 @@
151151 var readyForSeek = function() {
152152 _this.getPlayerElement();
153153 var newState = _this.playerElement.input.state;
154 - // if playing we are ready to do the
 154+ // if playing we are ready to do the
155155 if ( newState == 3 ) {
156156 _this.doSeek( percent );
157157 } else {
158 - // try to get player for 10 seconds:
 158+ // try to get player for 10 seconds:
159159 if ( rfsCount < 200 ) {
160160 setTimeout( readyForSeek, 50 );
161161 rfsCount++;
@@ -164,8 +164,8 @@
165165 }
166166 }
167167 readyForSeek();
168 - },
169 -
 168+ },
 169+
170170 /**
171171 * Updates the status time and player state
172172 */
@@ -182,21 +182,21 @@
183183 var iter = this.playerElement.log.messages.iterator();
184184 while ( iter.hasNext ) {
185185 var msg = iter.next();
186 - var msgtype = msg.type.toString();
187 - if ( ( msg.severity == 1 ) && ( msgtype == "input" ) )
188 - {
189 - mw.log( msg.message );
190 - }
 186+ var msgtype = msg.type.toString();
 187+ if ( ( msg.severity == 1 ) && ( msgtype == "input" ) )
 188+ {
 189+ mw.log( msg.message );
 190+ }
191191 }
192192 // clear the log once finished to avoid clogging
193193 this.playerElement.log.messages.clear();
194194 }
195 -
 195+
196196 var newState = this.playerElement.input.state;
197197 if ( this.prevState != newState ) {
198 - if ( newState == 0 )
 198+ if ( newState == 0 )
199199 {
200 - // current media has stopped
 200+ // current media has stopped
201201 this.onStop();
202202 }
203203 else if ( newState == 1 )
@@ -211,8 +211,8 @@
212212 }
213213 else if ( newState == 3 )
214214 {
215 - // current media is now playing
216 - this.onPlay();
 215+ // current media is now playing
 216+ this.onPlay();
217217 }
218218 else if ( this.playerElement.input.state == 4 ) {
219219 // current media is now paused
@@ -229,10 +229,10 @@
230230 // update the status and check timmer via universal parent monitor
231231 this.parent_monitor();
232232 },
233 -
 233+
234234 /**
235235 * Events:
236 - * @@note: should be localized:
 236+ * @@note: should be localized:
237237 */
238238 onOpen: function() {
239239 this.controlBuilder.setStatus( "Opening..." );
@@ -242,25 +242,25 @@
243243 },
244244 onPlay: function() {
245245 this.onPlaying();
246 - },
 246+ },
247247 onPlaying: function() {
248248 this.seeking = false;
249249 // for now trust the duration from url over vlc input.length
250250 if ( !this.getDuration() && this.playerElement.input.length > 0 )
251251 {
252 - // mw.log('setting duration to ' + this.playerElement.input.length /1000);
 252+ // mw.log('setting duration to ' + this.playerElement.input.length /1000);
253253 this.duration = this.playerElement.input.length / 1000;
254254 }
255255 this.vlcCurrentTime = this.playerElement.input.time / 1000;
256256 },
257 -
 257+
258258 /**
259259 * Get the embed player time
260260 */
261261 getPlayerElementTime: function(){
262262 return this.vlcCurrentTime;
263263 },
264 -
 264+
265265 onPause: function() {
266266 this.parent_pause(); // update the inteface if paused via native control
267267 },
@@ -269,77 +269,77 @@
270270 if ( !this.seeking )
271271 this.onClipDone();
272272 },
273 -
 273+
274274 /**
275275 * Handles play requests
276276 */
277 - play : function() {
 277+ play : function() {
278278 mw.log( 'f:vlcPlay' );
279279 // Update the interface
280 - this.parent_play();
 280+ this.parent_play();
281281 if ( this.getPlayerElement() ) {
282 - // plugin is already being present send play call:
 282+ // plugin is already being present send play call:
283283 // clear the message log and enable error logging
284284 if ( this.playerElement.log ) {
285285 this.playerElement.log.messages.clear();
286286 }
287287 if ( this.playerElement.playlist && typeof this.playerElement.playlist.play == 'function')
288288 this.playerElement.playlist.play();
289 -
 289+
290290 if( typeof this.playerElement.play == 'function' )
291 - this.playerElement.play();
292 -
 291+ this.playerElement.play();
 292+
293293 this.paused = false;
294 -
295 - // re-start the monitor:
 294+
 295+ // re-start the monitor:
296296 this.monitor();
297297 }
298298 },
299 -
 299+
300300 /**
301 - * Passes the Pause request to the plugin.
302 - * calls parent "pause" to update interface
 301+ * Passes the Pause request to the plugin.
 302+ * calls parent "pause" to update interface
303303 */
304304 pause : function() {
305305 this.parent_pause(); // update the interface if paused via native control
306 - if ( this.getPlayerElement() ) {
 306+ if ( this.getPlayerElement() ) {
307307 try{
308 - this.playerElement.playlist.togglePause();
 308+ this.playerElement.playlist.togglePause();
309309 } catch( e ){
310310 mw.log("EmbedPlayerVlc could not pause video " + e);
311311 }
312312 }
313313 },
314 -
 314+
315315 /**
316 - * Mutes the video
317 - * calls parent "toggleMute" to update interface
 316+ * Mutes the video
 317+ * calls parent "toggleMute" to update interface
318318 */
319319 toggleMute:function() {
320320 this.parent_toggleMute();
321321 if ( this.getPlayerElement() )
322322 this.playerElement.audio.toggleMute();
323323 },
324 -
 324+
325325 /**
326326 * Update the player volume
327327 * @pram {Float} percent Percent of total volume
328 - */
 328+ */
329329 setPlayerElementVolume: function ( percent ) {
330330 if ( this.getPlayerElement() ) {
331331 this.playerElement.audio.volume = percent * 100;
332332 }
333333 },
334 -
 334+
335335 /**
336336 * Gets the current volume
337337 * @return {Float} percent percent of total volume
338 - */
339 - getVolumen:function() {
 338+ */
 339+ getVolumen:function() {
340340 if ( this.getPlayerElement() )
341341 return this.playerElement.audio.volume / 100;
342342 },
343 -
 343+
344344 /**
345345 * Passes fullscreen request to plugin
346346 */
@@ -352,14 +352,14 @@
353353 mw.log("VlcEmbed toggle fullscreen : possible error: " + e);
354354 }
355355 }
356 - }
 356+ }
357357 },
358 -
 358+
359359 /**
360360 * Get the embed vlc object
361 - */
362 - getPlayerElement : function() {
 361+ */
 362+ getPlayerElement : function() {
363363 this.playerElement = $j( '#' + this.pid ).get(0);
364 - return this.playerElement;
 364+ return this.playerElement;
365365 }
366366 };
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerNative.js
@@ -1,170 +1,180 @@
22 /**
33 * Native embed library:
4 -*
 4+*
55 * Enables embedPlayer support for native html5 browser playback system
66 */
77 mw.EmbedPlayerNative = {
88
99 //Instance Name
1010 instanceOf: 'Native',
11 -
12 - // Counts the number of times we tried to access the video element
 11+
 12+ // Counts the number of times we tried to access the video element
1313 grab_try_count:0,
14 -
15 - // Flag to only load the video ( not play it )
16 - onlyLoadFlag:false,
17 -
18 - //Callback fired once video is "loaded"
 14+
 15+ // Flag to only load the video ( not play it )
 16+ onlyLoadFlag:false,
 17+
 18+ //Callback fired once video is "loaded"
1919 onLoadedCallback: null,
20 -
 20+
2121 //For retrying a player embed with a distinct url
22 - // NOTE: this bug workaround may no longer be applicable
 22+ // NOTE: this bug workaround may no longer be applicable
2323 urlAppend:'',
24 -
25 - // The previous "currentTime" to sniff seek actions
26 - // NOTE the bug where onSeeked does not seem fire consistently may no longer be applicable
 24+
 25+ // The previous "currentTime" to sniff seek actions
 26+ // NOTE the bug where onSeeked does not seem fire consistently may no longer be applicable
2727 prevCurrentTime: -1,
28 -
29 - // Store the progress event ( updated durring monitor )
 28+
 29+ // Store the progress event ( updated during monitor )
3030 progressEventData: null,
31 -
32 - // If the media loaded event has been fired
 31+
 32+ // If the media loaded event has been fired
3333 mediaLoadedFlag: null,
34 -
 34+
 35+ // All the native events per:
 36+ // http://www.w3.org/TR/html5/video.html#mediaevents
 37+ nativeEvents : [
 38+ 'loadstart',
 39+ 'progress',
 40+ 'suspend',
 41+ 'abort',
 42+ 'error',
 43+ 'emptied',
 44+ 'stalled',
 45+ 'play',
 46+ 'pause',
 47+ 'loadedmetadata',
 48+ 'loadeddata',
 49+ 'waiting',
 50+ 'playing',
 51+ 'canplay',
 52+ 'canplaythough',
 53+ 'seeking',
 54+ 'seeked',
 55+ 'timeupdate',
 56+ 'ended',
 57+ 'ratechange',
 58+ 'durationchange',
 59+ 'volumechange'
 60+ ],
 61+
3562 // Native player supported feature set
3663 supports: {
3764 'playHead' : true,
3865 'pause' : true,
3966 'fullscreen' : true,
4067 'timeDisplay' : true,
41 - 'volumeControl' : true,
 68+ 'volumeControl' : true,
4269 'overlays' : true
43 - },
44 -
45 - insertAndPlayingConfig : false,
46 -
47 - /**
48 - * updates the supported features given the "type of player"
 70+ },
 71+
 72+ /**
 73+ * updates the supported features given the "type of player"
4974 */
5075 updateFeatureSupport: function(){
5176 // iWhatever devices appear to have a broken
5277 // dom overlay implementation of video atm. (hopefully iphone OS 4 fixes this )
5378 if( mw.isMobileHTML5() ) {
5479 this.supports.overlays = false;
55 - }
 80+ }
5681 },
57 -
 82+
5883 /**
5984 * Return the embed code
6085 */
6186 doEmbedHTML : function () {
6287 var _this = this;
63 -
64 - // Reset some play state flags:
 88+
 89+ // Reset some play state flags:
6590 _this.bufferStartFlag = false;
6691 _this.bufferEndFlag = false;
67 -
 92+
6893 mw.log( "native play url:" + this.getSrc() + ' startOffset: ' + this.start_ntp + ' end: ' + this.end_ntp );
69 -
 94+
7095 // Check if using native controls and already the "pid" is already in the DOM
7196 if( this.useNativePlayerControls() && $j( '#' + this.pid ).length &&
7297 typeof $j( '#' + this.pid ).get(0).play != 'undefined' ) {
7398 _this.postEmbedJS();
7499 return ;
75100 }
76 -
 101+
77102 $j( this ).html(
78103 _this.getNativePlayerHtml()
79104 );
80 -
81 - // Directly run postEmbedJS ( if playerElement is not available it will retry )
 105+
 106+ // Directly run postEmbedJS ( if playerElement is not available it will retry )
82107 _this.postEmbedJS();
83108 },
84 -
 109+
85110 /**
86111 * Get the native player embed code.
87 - *
 112+ *
88113 * @param {object} playerAttribtues Attributes to be override in function call
89 - * @return {object} cssSet css to apply to the player
 114+ * @return {object} cssSet css to apply to the player
90115 */
91116 getNativePlayerHtml: function( playerAttribtues, cssSet ){
92117 if( !playerAttribtues) {
93118 playerAttribtues = {};
94119 }
95120 // Update required attributes
96 - if( !playerAttribtues[ 'id'] ) playerAttribtues['id'] = this.pid;
 121+ if( !playerAttribtues[ 'id'] ) playerAttribtues['id'] = this.pid;
97122 if( !playerAttribtues['src'] ) playerAttribtues['src'] = this.getSrc();
98 -
 123+
99124 // If autoplay pass along to attribute ( needed for iPad / iPod no js autoplay support
100125 if( this.autoplay ) {
101126 playerAttribtues['autoplay'] = 'true';
102127 }
103 -
104 -
 128+
 129+
105130 if( !cssSet ){
106131 cssSet = {};
107132 }
108133 // Set default width height to 100% of parent container
109134 if( !cssSet['width'] ) cssSet['width'] = '100%';
110135 if( !cssSet['height'] ) cssSet['height'] = '100%';
111 -
 136+
112137 // Also need to set the loop param directly for iPad / iPod
113138 if( this.loop ) {
114139 playerAttribtues['loop'] = 'true';
115140 }
116 -
 141+
117142 var tagName = ( this.isAudio() ) ? 'audio' : 'video';
118 -
 143+
119144 return $j( '<' + tagName + ' />' )
120 - // Add the special nativeEmbedPlayer to avoid any rewrites of of this video tag.
 145+ // Add the special nativeEmbedPlayer to avoid any rewrites of of this video tag.
121146 .addClass( 'nativeEmbedPlayerPid' )
122147 .attr( playerAttribtues )
123148 .css( cssSet );
124 - },
125 -
 149+ },
 150+
126151 /**
127 - * Post element javascript, binds event listeners and starts monitor
128 - */
 152+ * Post element javascript, binds event listeners and starts monitor
 153+ */
129154 postEmbedJS: function() {
130155 var _this = this;
131156 mw.log( "f:native:postEmbedJS:" );
132157
133 - // Setup local pointer:
 158+ // Setup local pointer:
134159 var vid = this.getPlayerElement();
135 - if ( typeof this.playerElement != 'undefined' ) {
136 - // Apply media element bindings:
137 - this.applyMediaElementBindings();
138 -
139 - // Check for load flag
140 - if ( this.onlyLoadFlag ) {
141 - vid.pause();
142 - vid.load();
143 - } else {
144 - // Issue play request
145 - vid.play();
146 - }
147 -
148 - setTimeout( function() {
149 - _this.monitor();
150 - }, 100 );
151 -
152 - } else {
153 - // False inserts don't seem to be as much of a problem as before:
154 - mw.log( 'Could not grab vid obj trying again:' + typeof this.playerElement );
155 - this.grab_try_count++;
156 - if ( this.grab_count == 20 ) {
157 - mw.log( 'Could not get vid object after 20 tries re-run: getEmbedObj() ?' ) ;
158 - } else {
159 - setTimeout( function() {
160 - _this.postEmbedJS();
161 - }, 150 );
162 - }
163 -
 160+ // Apply media element bindings:
 161+ this.applyMediaElementBindings();
 162+
 163+ // Check for load flag
 164+ if ( this.onlyLoadFlag ) {
 165+ vid.pause();
 166+ vid.load();
 167+ } else {
 168+ // Issue play request
 169+ vid.play();
164170 }
 171+
 172+ setTimeout( function() {
 173+ _this.monitor();
 174+ }, 100 );
165175 },
166 -
 176+
167177 /**
168 - * Apply media element bindings
 178+ * Apply media element bindings
169179 */
170180 applyMediaElementBindings: function(){
171181 var _this = this;
@@ -173,46 +183,47 @@
174184 mw.log( " Error: applyMediaElementBindings without player elemnet");
175185 return ;
176186 }
177 - // Bind events to local js methods:
178 - vid.addEventListener( 'canplaythrogh', function() { $j( _this ).trigger('canplaythrough'); }, true);
 187+
 188+ // Bind events to local js methods:
 189+ vid.addEventListener( 'canplaythrough', function() { $j( _this ).trigger('canplaythrough'); }, true);
179190 vid.addEventListener( 'loadedmetadata', function() { _this.onloadedmetadata() }, true);
180 - vid.addEventListener( 'progress', function( e ) { if( _this.onprogress ) { _this.onprogress( e ); } }, true);
181 - vid.addEventListener( 'ended', function() { _this.onended() }, true);
 191+ vid.addEventListener( 'progress', function( e ) { if( _this.onprogress ) { _this.onprogress( e ); } }, true);
 192+ vid.addEventListener( 'ended', function() { _this.onended() }, true);
182193 vid.addEventListener( 'seeking', function() { _this.onSeeking() }, true);
183 - vid.addEventListener( 'seeked', function() { _this.onSeeked() }, true);
184 -
 194+ vid.addEventListener( 'seeked', function() { _this.onSeeked() }, true);
 195+
185196 vid.addEventListener( 'pause', function() { if( _this.onPaused ) { _this.onPaused() } }, true );
186 - vid.addEventListener( 'play', function(){ _this.onPlay() }, true );
 197+ vid.addEventListener( 'play', function(){ _this.onPlay() }, true );
187198 vid.addEventListener( 'volumechange', function(){ _this.onVolumeChange() } , true );
188199 },
189 -
 200+
190201 // basic monitor function to update buffer
191202 monitor: function(){
192203 var _this = this;
193204 var vid = _this.getPlayerElement();
194 -
 205+
195206 // Update the bufferedPercent
196 - if( vid && vid.buffered && vid.buffered.end && vid.duration ) {
 207+ if( vid && vid.buffered && vid.buffered.end && vid.duration ) {
197208 this.bufferedPercent = (vid.buffered.end(0) / vid.duration);
198 - }
 209+ }
199210 _this.parent_monitor();
200211 },
201 -
202 -
 212+
 213+
203214 /**
204 - * Issue a seeking request.
 215+ * Issue a seeking request.
205216 *
206217 * @param {Float} percentage
207218 */
208219 doSeek: function( percentage ) {
209 - mw.log( 'Native::doSeek p: ' + percentage + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
 220+ mw.log( 'Native::doSeek p: ' + percentage + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
210221 this.seeking = true;
211222 // Run the seeking hook
212 - $j( this.embedPlayer ).trigger( 'onSeek' );
213 -
 223+ $j( this.embedPlayer ).trigger( 'onSeek' );
 224+
214225 // Run the onSeeking interface update
215226 this.controlBuilder.onSeek();
216 -
 227+
217228 // @@todo check if the clip is loaded here (if so we can do a local seek)
218229 if ( this.supportsURLTimeEncoding() ) {
219230 // Make sure we could not do a local seek instead:
@@ -220,18 +231,18 @@
221232 mw.log( "do local seek " + percentage + ' is already buffered < ' + this.bufferedPercent );
222233 this.doNativeSeek( percentage );
223234 } else {
224 - // We support URLTimeEncoding call parent seek:
 235+ // We support URLTimeEncoding call parent seek:
225236 this.parent_doSeek( percentage );
226237 }
227238 } else if ( this.playerElement && this.playerElement.duration ) {
228 - // (could also check bufferedPercent > percentage seek (and issue oggz_chop request or not)
 239+ // (could also check bufferedPercent > percentage seek (and issue oggz_chop request or not)
229240 this.doNativeSeek( percentage );
230241 } else {
231 - // try to do a play then seek:
 242+ // try to do a play then seek:
232243 this.doPlayThenSeek( percentage )
233244 }
234245 },
235 -
 246+
236247 /**
237248 * Do a native seek by updating the currentTime
238249 * @param {float} percentage Percent to seek to of full time
@@ -240,83 +251,13 @@
241252 var _this = this;
242253 mw.log( 'native::doNativeSeek::' + percentage );
243254 this.seeking = true;
244 - this.seek_time_sec = 0;
 255+ this.seek_time_sec = 0;
245256 this.setCurrentTime( ( percentage * this.duration ) , function(){
246257 _this.seeking = false;
247258 _this.monitor();
248 - })
 259+ })
249260 },
250 -
251 - insertAndPlaySource: function( src , options ){
252 - mw.log("NativeEmbed:: insertAndPlaySource: " + src + ' insertAndPlayingConfig:' + this.insertAndPlayingConfig);
253 - if(!options)
254 - options = {};
255 -
256 - if( options.lockUI ){
257 - this.playerElement.controls = false;
258 - }
259 -
260 - // Make sure to capture the original source
261 - if(! this.insertAndPlayingConfig ){
262 - //alert( 'setup this.insertAndPlayingConfig ');
263 - this.insertAndPlayingConfig = {
264 - 'src' : this.getSrc(),
265 - 'time' : this.currentTime,
266 - 'callback' : options.callback,
267 - 'restoreControls' : options.lockUI
268 - }
269 - }
270 - // Try to directly playback the source
271 - this.switchSrc( src );
272 -
273 - },
274 - restoreSourcePlayback: function( ){
275 - var _this = this;
276 - mw.log( "RestoreSourcePlayback:: empty out insertAndPlayingConfig" );
277 - if( !this.insertAndPlayingConfig) {
278 - mw.log("Error: called restored playback with empty insertAndPlayingConfig")
279 - return;
280 - }
281 - this.switchSrc( this.insertAndPlayingConfig.src );
282 - //this.playerElement.play();
283 - // Remove insert and playing config flag
284 - this.insertAndPlayingConfig = false;
285 -
286 - var time = this.insertAndPlayingConfig.time;
287 - var callback = this.insertAndPlayingConfig.callback;
288 -
289 - // run the seek:
290 - this.setCurrentTime( time ,function(){
291 - if( this.insertAndPlayingConfig.restoreControls ){
292 - this.playerElement.controls = true;
293 - }
294 - });
295 - // Give some time for ipad to figure out whats going on:
296 - setTimeout(function(){
297 - _this.playerElement.load();
298 - _this.playerElement.play();
299 - },100);
300 -
301 - //alert("insertAndPlayingConfig:: " + this.insertAndPlayingConfig);
302 - // Run the callback
303 - if( callback ){
304 - callback();
305 - }
306 - },
307 - switchSrc: function( src ){
308 - mw.log( 'switchSrc' )
309 - if( this.getPlayerElement() ){
310 - try{
311 - //this.playerElement.pause();
312 - this.playerElement.src = src;
313 - this.playerElement.load();
314 - this.playerElement.play();
315 - } catch( e ){
316 - mw.log("Error: possible error in swiching source playback");
317 - }
318 - }
319 - },
320 -
 261+
321262 /**
322263 * Seek in a existing stream
323264 *
@@ -328,12 +269,12 @@
329270 this.play();
330271 var retryCount = 0;
331272 var readyForSeek = function() {
332 - _this.getPlayerElement();
 273+ _this.getPlayerElement();
333274 // If we have duration then we are ready to do the seek
334275 if ( _this.playerElement && _this.playerElement.duration ) {
335276 _this.doNativeSeek( percentage );
336277 } else {
337 - // Try to get player for 40 seconds:
 278+ // Try to get player for 40 seconds:
338279 // (it would be nice if the onmetadata type callbacks where fired consistently)
339280 if ( retryCount < 800 ) {
340281 setTimeout( readyForSeek, 50 );
@@ -345,36 +286,42 @@
346287 }
347288 readyForSeek();
348289 },
349 -
 290+
350291 /**
351292 * Set the current time with a callback
352 - *
 293+ *
353294 * @param {Float} position Seconds to set the time to
354 - * @param {Function} callback Function called once time has been set.
 295+ * @param {Function} callback Function called once time has been set.
355296 */
356 - setCurrentTime: function( time , callback, callbackCount ) {
357 - var _this = this;
 297+ setCurrentTime: function( time , callback, callbackCount ) {
 298+ var _this = this;
358299 if( !callbackCount )
359300 callbackCount = 0;
360 - this.getPlayerElement();
 301+ this.getPlayerElement();
361302 if( _this.playerElement.readyState >= 1 ){
362303 if( _this.playerElement.currentTime == time ){
363304 callback();
364 - return;
365 - }
366 - var once = function( event ) {
 305+ return;
 306+ }
 307+ var once = function( event ) {
367308 if( callback ){
368309 callback();
369310 }
370311 _this.playerElement.removeEventListener( 'seeked', once, false );
371 - };
372 - // Assume we will get to add the Listener before the seek is done
 312+ };
 313+ // Assume we will get to add the Listener before the seek is done
373314 _this.playerElement.addEventListener( 'seeked', once, false );
374 - _this.playerElement.currentTime = time;
375 - } else {
 315+ try {
 316+ _this.playerElement.currentTime = time;
 317+ } catch (e) {
 318+ mw.log("Could not seek to this point. Unbuffered point.");
 319+ callback();
 320+ return;
 321+ }
 322+ } else {
376323 if( callbackCount >= 300 ){
377324 mw.log("Error with seek request, media never in ready state");
378 - return ;
 325+ return ;
379326 }
380327 setTimeout( function(){
381328 _this.setCurrentTime( time, callback , callbackCount++);
@@ -385,63 +332,63 @@
386333 /**
387334 * Get the embed player time
388335 */
389 - getPlayerElementTime: function() {
390 - var _this = this;
 336+ getPlayerElementTime: function() {
 337+ var _this = this;
391338 // Make sure we have .vid obj
392 - this.getPlayerElement();
393 -
 339+ this.getPlayerElement();
 340+
394341 if ( !this.playerElement ) {
395 - mw.log( 'Error: mwEmbedPlayer::getPlayerElementTime: missing ' + this.id + ' stop monitor' );
 342+ mw.log( 'mwEmbedPlayer::getPlayerElementTime: ' + this.id + ' not in dom ( stop monitor)' );
396343 return false;
397 - }
398 - // Return the playerElement currentTime
 344+ }
 345+ // Return the playerElement currentTime
399346 return this.playerElement.currentTime;
400347 },
401 -
 348+
402349 /**
403350 * Get video src URI
404 - * appends this.urlAppend for unique urls for re-requesting src urls on broken playback
 351+ * appends this.urlAppend for unique urls for re-requesting src urls on broken playback
405352 */
406353 getSrc: function() {
407354 var src = this.parent_getSrc();
408 - if ( this.urlAppend != '' )
 355+ if ( this.urlAppend != '' )
409356 return src + ( ( src.indexOf( '?' ) == -1 ) ? '?':'&' ) + this.urlAppend;
410357 return src;
411 - },
412 -
 358+ },
 359+
413360 /**
414361 * Pause the video playback
415362 * calls parent_pause to update the interface
416363 */
417364 pause: function( ) {
418 - this.getPlayerElement();
419 - this.parent_pause(); // update interface
 365+ this.getPlayerElement();
 366+ this.parent_pause(); // update interface
420367 if ( this.playerElement ) { // update player
421368 if( !this.playerElement.paused ){
422369 this.playerElement.pause();
423370 }
424371 }
425372 },
426 -
 373+
427374 /**
428375 * Play back the video stream
429376 * calls parent_play to update the interface
430377 */
431378 play: function( ) {
432 -
433 - this.getPlayerElement();
 379+
 380+ this.getPlayerElement();
434381 this.parent_play(); // update interface
435382 if ( this.playerElement && this.playerElement.play ) {
436383 // issue a play request if the media is paused:
437384 if( this.playerElement.paused ){
438385 this.playerElement.play();
439386 }
440 - // re-start the monitor:
 387+ // re-start the monitor:
441388 this.monitor();
442389 }
443390 },
444391 /**
445 - * Stop the player ( end all listeners )
 392+ * Stop the player ( end all listeners )
446393 */
447394 stop:function(){
448395 if( this.playerElement ){
@@ -449,61 +396,62 @@
450397 }
451398 this.parent_stop();
452399 },
453 -
 400+
454401 /**
455402 * Toggle the Mute
456403 * calls parent_toggleMute to update the interface
457 - */
 404+ */
458405 toggleMute: function() {
459406 this.parent_toggleMute();
460407 this.getPlayerElement();
461408 if ( this.playerElement )
462409 this.playerElement.muted = this.muted;
463410 },
464 -
 411+
465412 /**
466413 * Update Volume
467414 *
468415 * @param {Float} percentage Value between 0 and 1 to set audio volume
469 - */
 416+ */
470417 setPlayerElementVolume : function( percentage ) {
471418 if ( this.getPlayerElement() ) {
472 - // Disable mute if positive volume
 419+ // Disable mute if positive volume
473420 if( percentage != 0 ) {
474421 this.playerElement.muted = false;
475422 }
476423 this.playerElement.volume = percentage;
477424 }
478425 },
479 -
 426+
480427 /**
481428 * get Volume
482429 *
483 - * @return {Float}
 430+ * @return {Float}
484431 * Audio volume between 0 and 1.
485 - */
486 - getPlayerElementVolume: function() {
 432+ */
 433+ getPlayerElementVolume: function() {
487434 if ( this.getPlayerElement() ) {
488435 return this.playerElement.volume;
489436 }
490437 },
491438 /**
492439 * get the native muted state
493 - */
 440+ */
494441 getPlayerElementMuted: function(){
495442 if ( this.getPlayerElement() ) {
496443 return this.playerElement.muted;
497444 }
498445 },
499 -
 446+
500447 /**
501448 * Handle volume change are handled via "monitor" as to not do too many binding triggers per seconds.
502449 */
503450 onVolumeChange: function(){
504451 //mw.log( "native::volumechange::trigger" );
505452 //this.volume = this.playerElement.volume;
 453+ $j( this ).trigger( 'volumechange' );
506454 },
507 -
 455+
508456 /**
509457 * Get the native media duration
510458 */
@@ -512,20 +460,20 @@
513461 return this.playerElement.duration;
514462 }
515463 },
516 -
 464+
517465 /**
518466 * load the video stream with a callback fired once the video is "loaded"
519467 *
520468 * @parma {Function} callbcak Function called once video is loaded
521469 */
522470 load: function( callback ) {
523 - this.getPlayerElement();
 471+ this.getPlayerElement();
524472 if ( !this.playerElement ) {
525473 // No vid loaded
526474 mw.log( 'native::load() ... doEmbed' );
527475 this.onlyLoadFlag = true;
528476 this.doEmbedHTML();
529 - this.onLoadedCallback = callback;
 477+ this.onLoadedCallback = callback;
530478 } else {
531479 // Should not happen offten
532480 this.playerElement.load();
@@ -533,125 +481,123 @@
534482 callback();
535483 }
536484 },
537 -
 485+
538486 /**
539 - * Get /update the playerElement value
540 - */
541 - getPlayerElement: function () {
 487+ * Get /update the playerElement value
 488+ */
 489+ getPlayerElement: function () {
542490 this.playerElement = $j( '#' + this.pid ).get( 0 );
543491 return this.playerElement;
544492 },
545 -
 493+
546494 /**
547 - * Bindings for the Video Element Events
 495+ * Bindings for the Video Element Events
548496 */
549 -
 497+
550498 /**
551499 * Local method for seeking event
552 - * fired when "seeking"
 500+ * fired when "seeking"
553501 */
554 - onSeeking: function() {
 502+ onSeeking: function() {
555503 mw.log( "native:onSeeking");
556 - // Trigger the html5 seeking event
 504+ // Trigger the html5 seeking event
557505 //( if not already set from interface )
558 - if( !this.seeking ) {
 506+ if( !this.seeking ) {
559507 this.seeking = true;
560508 // Run the seeking hook (somewhat redundant )
561509 $j( this ).trigger( 'onSeek' );
562 -
 510+
563511 // Run the onSeeking interface update
564 - this.controlBuilder.onSeek();
565 -
 512+ this.controlBuilder.onSeek();
 513+
566514 // Trigger the html5 "seeking" trigger
567 - mw.log("native:seeking:trigger:: " + this.seeking);
 515+ mw.log("native:seeking:trigger:: " + this.seeking);
568516 $j( this ).trigger( 'seeking' );
569517 }
570518 },
571 -
 519+
572520 /**
573521 * Local method for seeked event
574 - * fired when done seeking
 522+ * fired when done seeking
575523 */
576524 onSeeked: function() {
577525 mw.log("native:onSeeked");
578 - this.seeking = false;
 526+
579527 mw.log("native:onSeeked:trigger");
580 - // Trigger the html5 action on the parent
581 - $j( this ).trigger( 'seeked' );
 528+ // Trigger the html5 action on the parent
 529+ if( this.seeking && this.useNativePlayerControls() ){
 530+ this.seeking = false;
 531+ $j( this ).trigger( 'seeked' );
 532+ }
 533+ this.seeking = false;
582534 },
583 -
 535+
584536 /**
585537 * Handle the native paused event
586 - */
 538+ */
587539 onPaused: function(){
588540 mw.log( "EmbedPlayer:native: OnPaused" );
589 - this.parent_pause();
 541+ this.parent_pause();
590542 },
591 -
 543+
592544 /**
593 - * Handle the native play event
 545+ * Handle the native play event
594546 */
595547 onPlay: function(){
596 - mw.log("EmbedPlayer:native:: OnPlay");
597 - // Update the interface
 548+ mw.log("EmbedPlayer:native:: OnPlay");
 549+ // Update the interface ( if paused )
598550 this.parent_play();
599551 },
600 -
601 - /**
 552+
 553+ /**
602554 * Local method for metadata ready
603555 * fired when metadata becomes available
604556 *
605 - * Used to update the media duration to
606 - * accurately reflect the src duration
 557+ * Used to update the media duration to
 558+ * accurately reflect the src duration
607559 */
608560 onloadedmetadata: function() {
609561 this.getPlayerElement();
610 - if ( this.playerElement && ! isNaN( this.playerElement.duration ) ) {
611 - mw.log( 'f:onloadedmetadata metadata ready Update duration:' + this.playerElement.duration + ' old dur: ' + this.getDuration() );
 562+ if ( this.playerElement && ! isNaN( this.playerElement.duration ) ) {
 563+ mw.log( 'f:onloadedmetadata metadata ready Update duration:' + this.playerElement.duration + ' old dur: ' + this.getDuration() );
612564 this.duration = this.playerElement.duration;
613565 }
614 -
 566+
615567 //Fire "onLoaded" flags if set
616568 if( typeof this.onLoadedCallback == 'function' ) {
617569 this.onLoadedCallback();
618570 }
619 -
 571+
620572 // Tigger "media loaded"
621573 if( ! this.mediaLoadedFlag ){
622574 $j( this ).trigger( 'mediaLoaded' );
623575 this.mediaLoadedFlag = true;
624576 }
625577 },
626 -
 578+
627579 /**
628580 * Local method for progress event
629581 * fired as the video is downloaded / buffered
630582 *
631583 * Used to update the bufferedPercent
632584 */
633 - onprogress: function( e ) {
 585+ onprogress: function( e ) {
634586 if( e.loaded && e.total ) {
635 - this.bufferedPercent = e.loaded / e.total;
 587+ this.bufferedPercent = e.loaded / e.total;
636588 this.progressEventData = e.loaded;
637 - }
 589+ }
638590 },
639 -
 591+
640592 /**
641593 * Local method for progress event
642594 * fired as the video is downloaded / buffered
643595 *
644596 * Used to update the bufferedPercent
645 - */
 597+ */
646598 onended: function() {
647 - var _this = this;
648 - mw.log( 'EmbedPlayer:native: onended:' + this.playerElement.currentTime + ' real dur:' + this.getDuration() +
649 - ' insertAndPlayingConfig: ' + this.insertAndPlayingConfig);
650 -
651 - if( this.insertAndPlayingConfig ){
652 - this.restoreSourcePlayback();
653 - this.insertAndPlayingConfig = false;
654 - return ;
655 - }
 599+ var _this = this;
 600+ mw.log( 'EmbedPlayer:native: onended:' + this.playerElement.currentTime + ' real dur:' + this.getDuration() );
 601+
656602 this.onClipDone();
657603 }
658604 };
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerKplayer.js
@@ -42,7 +42,7 @@
4343 // Use a relative url if the protocal is file://
4444 if( mw.parseUri( document.URL).protocol == 'file' ) {
4545 playerPath = mw.getRelativeMwEmbedPath() + 'modules/EmbedPlayer/binPlayers/kaltura-player';
46 - flashvars.entryId = _this.getSrc();
 46+ flashvars.entryId = _this.getSrc();
4747 }
4848
4949 flashvars.debugMode = "true";
@@ -92,18 +92,17 @@
9393
9494 // Direct object embed
9595 /*$j( this ).html(
96 - '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="780" height="420">'+
97 - '<param name="movie" value="myContent.swf" />'+
98 - '<!--[if !IE]>-->'+
99 - '<object type="application/x-shockwave-flash" data="myContent.swf" width="780" height="420">'+
100 - '<!--<![endif]-->'+
101 - '<p> error with flash embed</p>'
102 - '<!--[if !IE]>-->'+
103 - '</object>'+
104 - '<!--<![endif]-->'+
105 - '</object>'
106 - )*/
107 -
 96+ '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="780" height="420">'+
 97+ '<param name="movie" value="myContent.swf" />'+
 98+ '<!--[if !IE]>-->'+
 99+ '<object type="application/x-shockwave-flash" data="myContent.swf" width="780" height="420">'+
 100+ '<!--<![endif]-->'+
 101+ '<p> error with flash embed</p>'
 102+ '<!--[if !IE]>-->'+
 103+ '</object>'+
 104+ '<!--<![endif]-->'+
 105+ '</object>'
 106+ )*/
108107
109108 setTimeout( function() {
110109 _this.postEmbedJS();
@@ -217,7 +216,7 @@
218217 if ( this.supportsURLTimeEncoding() ){
219218
220219 // Make sure we could not do a local seek instead:
221 - if ( !( percentage < this.bufferedPercent && this.playerElement.duration && !this.didSeekJump )) {
 220+ if ( !( percentage < this.bufferedPercent && this.playerElement.duration && !this.didSeekJump )) {
222221 // We support URLTimeEncoding call parent seek:
223222 this.parent_doSeek( percentage );
224223 return;
@@ -227,7 +226,7 @@
228227 if( this.playerElement ) {
229228 var seekTime = percentage * this.getDuration();
230229 // Issue the seek to the flash player:
231 - this.playerElement.sendNotification('doSeek', seekTime);
 230+ this.playerElement.sendNotification('doSeek', seekTime);
232231
233232 // Kdp is missing seek done callback
234233 setTimeout(function() {
@@ -262,7 +261,7 @@
263262 if ( _this.playerElement && _this.playerElement.sendNotification && _this.getDuration() && _this.bufferedPercent ) {
264263 var seekTime = percentage * _this.getDuration();
265264 // Issue the seek to the flash player:
266 - _this.playerElement.sendNotification('doSeek', seekTime);
 265+ _this.playerElement.sendNotification('doSeek', seekTime);
267266 } else {
268267 // Try to get player for 20 seconds:
269268 if ( getPlayerCount < 400 ) {
@@ -297,7 +296,7 @@
298297 * function called by flash when the total media size changes
299298 */
300299 onBytesTotalChange: function(data, id) {
301 - this.bytesTotal = data.newValue ;
 300+ this.bytesTotal = data.newValue ;
302301 },
303302
304303 /**
@@ -306,11 +305,11 @@
307306 onBytesDownloadedChange: function( data, id){
308307 mw.log( 'onBytesDownloadedChange');
309308 this.bytesLoaded = data.newValue;
310 - this.bufferedPercent = this.bytesLoaded / this.bytesTotal;
 309+ this.bufferedPercent = this.bytesLoaded / this.bytesTotal;
311310
312311 // Fire the parent html5 action
313312 $j( this ).trigger( 'progress', {
314 - 'loaded' : this.bytesLoaded,
 313+ 'loaded' : this.bytesLoaded,
315314 'total' : this.bytesTotal
316315 } );
317316 },

Status & tagging log