Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.php |
— | — | @@ -17,6 +17,7 @@ |
18 | 18 | |
19 | 19 | "mw.EmbedPlayer" => array( |
20 | 20 | 'scripts' => array( |
| 21 | + "resources/mw.processEmbedPlayers.js", |
21 | 22 | "resources/mw.EmbedPlayer.js", |
22 | 23 | "resources/skins/mw.PlayerControlBuilder.js", |
23 | 24 | ), |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js |
— | — | @@ -125,331 +125,6 @@ |
126 | 126 | |
127 | 127 | |
128 | 128 | /** |
129 | | - * Selector based embedPlayer processing |
130 | | - * |
131 | | - * @param {Function=} |
132 | | - * callback Optional Function to be called once video interfaces |
133 | | - * are ready |
134 | | - * |
135 | | - */ |
136 | | -mw.processEmbedPlayers = function( playerSelect, callback ) { |
137 | | - mw.log( 'EmbedPlayer:: processEmbedPlayers' ); |
138 | | - |
139 | | - // Check if the selected player set is ready if ready issue the parent callback |
140 | | - var areSelectedPlayersReady = function(){ |
141 | | - var playersLoaded = true; |
142 | | - $(playerSelect).each(function(inx, player){ |
143 | | - if( ! $( player ).get(0).doneLoading ){ |
144 | | - playersLoaded = false; |
145 | | - return false; |
146 | | - } |
147 | | - }) |
148 | | - if( playersLoaded ){ |
149 | | - if( callback ) |
150 | | - callback(); |
151 | | - } |
152 | | - } |
153 | | - |
154 | | - /** |
155 | | - * Adds a player element for the embedPlayer to rewrite |
156 | | - * |
157 | | - * uses embedPlayer interface on audio / video elements uses mvPlayList |
158 | | - * interface on playlist elements |
159 | | - * |
160 | | - * Once a player interface is established the following chain of functions |
161 | | - * are called; |
162 | | - * |
163 | | - * _this.checkPlayerSources() |
164 | | - * _this.setupSourcePlayer() |
165 | | - * _this.inheritEmbedPlayer() |
166 | | - * _this.selectedPlayer.load() |
167 | | - * _this.showPlayer() |
168 | | - * |
169 | | - * @param {Element} |
170 | | - * playerElement DOM element to be swapped |
171 | | - * @param {Object} |
172 | | - * [Optional] attributes Extra attributes to apply to the player |
173 | | - * interface |
174 | | - */ |
175 | | - var addPlayerElement = function( playerElement ) { |
176 | | - var _this = this; |
177 | | - mw.log('EmbedPlayer:: addElement:: ' + playerElement.id ); |
178 | | - |
179 | | - |
180 | | - // Be sure to "stop" the target ( Firefox 3x keeps playing |
181 | | - // the video even though its been removed from the DOM ) |
182 | | - if( playerElement.pause ){ |
183 | | - playerElement.pause(); |
184 | | - } |
185 | | - |
186 | | - // Allow modules to override the wait for metadata flag: |
187 | | - $( mw ).trigger( 'checkPlayerWaitForMetaData', playerElement ); |
188 | | - |
189 | | - // DOM *could* load height, width and duration eventually, in some browsers |
190 | | - // By default, don't bother waiting for this. |
191 | | - var waitForMeta = false; |
192 | | - |
193 | | - // if a plugin has told us not to waitForMeta, don't |
194 | | - if ( playerElement.waitForMeta !== false ) { |
195 | | - // Check if we should wait for metadata, after all |
196 | | - waitForMeta = waitForMetaCheck( playerElement ); |
197 | | - } |
198 | | - |
199 | | - var ranPlayerSwapFlag = false; |
200 | | - |
201 | | - // Local callback to runPlayer swap once playerElement has metadata |
202 | | - function runPlayerSwap() { |
203 | | - // Don't run player swap twice |
204 | | - if( ranPlayerSwapFlag ){ |
205 | | - return ; |
206 | | - } |
207 | | - ranPlayerSwapFlag = true; |
208 | | - mw.log("EmbedPlayer::runPlayerSwap::" + $( playerElement ).attr('id') ); |
209 | | - |
210 | | - var playerInterface = new mw.EmbedPlayer( playerElement ); |
211 | | - var swapPlayer = swapEmbedPlayerElement( playerElement, playerInterface ); |
212 | | - |
213 | | - // Trigger the EmbedPlayerNewPlayer for embedPlayer interface |
214 | | - mw.log("EmbedPlayer::EmbedPlayerNewPlayer:trigger " + playerInterface.id ); |
215 | | - |
216 | | - // TODO: (from review) $( '#' + playerInterface.id ).get(0) is, theoreticaly, the same as swapPlayer and they might be interchangeable. |
217 | | - $( mw ).trigger ( 'EmbedPlayerNewPlayer', $( '#' + playerInterface.id ).get(0) ); |
218 | | - |
219 | | - // Add a player ready binding: |
220 | | - $( '#' + playerInterface.id ).bind( 'playerReady', areSelectedPlayersReady ); |
221 | | - |
222 | | - // Issue the checkPlayerSources call to the new player |
223 | | - // interface: make sure to use the element that is in the DOM: |
224 | | - // TODO: (from review) should be same as swapPlayer? |
225 | | - $( '#' + playerInterface.id ).get(0).checkPlayerSources(); |
226 | | - |
227 | | - } |
228 | | - |
229 | | - if( waitForMeta && mw.getConfig('EmbedPlayer.WaitForMeta' ) ) { |
230 | | - mw.log('EmbedPlayer::WaitForMeta ( video missing height (' + |
231 | | - $( playerElement ).attr('height') + '), width (' + |
232 | | - $( playerElement ).attr('width') + ') or duration: ' + |
233 | | - $( playerElement ).attr('duration') |
234 | | - ); |
235 | | - $( playerElement ).bind("loadedmetadata", runPlayerSwap ); |
236 | | - |
237 | | - // Time-out of 5 seconds ( maybe still playable but no timely |
238 | | - // metadata ) |
239 | | - setTimeout( runPlayerSwap, 5000 ); |
240 | | - return ; |
241 | | - } else { |
242 | | - runPlayerSwap(); |
243 | | - return ; |
244 | | - } |
245 | | - }; |
246 | | - |
247 | | - /** |
248 | | - * Check if we should wait for metadata. |
249 | | - * |
250 | | - * @return true if the size is "likely" to be updated by waiting for metadata |
251 | | - * false if the size has been set via an attribute or is already loaded |
252 | | - */ |
253 | | - var waitForMetaCheck = function( playerElement ){ |
254 | | - var waitForMeta = false; |
255 | | - |
256 | | - // Don't wait for metadata for non html5 media elements |
257 | | - if( !playerElement ){ |
258 | | - return false; |
259 | | - } |
260 | | - if( !playerElement.tagName || ( playerElement.tagName.toLowerCase() != 'audio' && playerElement.tagName.toLowerCase() != 'video' ) ){ |
261 | | - return false; |
262 | | - } |
263 | | - // If we don't have a native player don't wait for metadata |
264 | | - if( !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'oggNative') && |
265 | | - !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'webmNative') && |
266 | | - !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'h264Native' ) ) |
267 | | - { |
268 | | - return false; |
269 | | - } |
270 | | - |
271 | | - |
272 | | - var width = $( playerElement ).css( 'width' ); |
273 | | - var height = $( playerElement ).css( 'height' ); |
274 | | - |
275 | | - // Css video defaults ( firefox ) |
276 | | - if( $( playerElement ).css( 'width' ) == '300px' && |
277 | | - $( playerElement ).css( 'height' ) == '150px' |
278 | | - ){ |
279 | | - waitForMeta = true; |
280 | | - } else { |
281 | | - // Check if we should wait for duration: |
282 | | - if( $( playerElement ).attr( 'duration') || |
283 | | - $( playerElement ).attr('data-durationhint') |
284 | | - ){ |
285 | | - // height, width and duration set; do not wait for meta data: |
286 | | - return false; |
287 | | - } else { |
288 | | - waitForMeta = true; |
289 | | - } |
290 | | - } |
291 | | - |
292 | | - // Firefox ~ sometimes~ gives -1 for unloaded media |
293 | | - if ( $(playerElement).attr( 'width' ) == -1 || $(playerElement).attr( 'height' ) == -1 ) { |
294 | | - waitForMeta = true; |
295 | | - } |
296 | | - |
297 | | - // Google Chrome / safari gives 0 width height for unloaded media |
298 | | - if( $(playerElement).attr( 'width' ) === 0 || |
299 | | - $(playerElement).attr( 'height' ) === 0 |
300 | | - ) { |
301 | | - waitForMeta = true; |
302 | | - } |
303 | | - |
304 | | - // Firefox default width height is ~sometimes~ 150 / 300 |
305 | | - if( this.height == 150 && this.width == 300 ){ |
306 | | - waitForMeta = true; |
307 | | - } |
308 | | - |
309 | | - // Make sure we have a src attribute or source child |
310 | | - // ( i.e not a video tag to be dynamically populated or looked up from |
311 | | - // xml resource description ) |
312 | | - if( waitForMeta && |
313 | | - ( |
314 | | - $( playerElement ).attr('src') || |
315 | | - $( playerElement ).find("source[src]").length !== 0 |
316 | | - ) |
317 | | - ) { |
318 | | - // Detect src type ( if no type set ) |
319 | | - return true; |
320 | | - } else { |
321 | | - // playerElement is not likely to update its meta data ( no src ) |
322 | | - return false; |
323 | | - } |
324 | | - }; |
325 | | - |
326 | | - /** |
327 | | - * swapEmbedPlayerElement |
328 | | - * |
329 | | - * Takes a video element as input and swaps it out with an embed player interface |
330 | | - * |
331 | | - * @param {Element} |
332 | | - * targetElement Element to be swapped |
333 | | - * @param {Object} |
334 | | - * playerInterface Interface to swap into the target element |
335 | | - */ |
336 | | - var swapEmbedPlayerElement = function( targetElement, playerInterface ) { |
337 | | - mw.log( 'EmbedPlayer::swapEmbedPlayerElement: ' + targetElement.id ); |
338 | | - // Create a new element to swap the player interface into |
339 | | - var swapPlayerElement = document.createElement('div'); |
340 | | - |
341 | | - // Add a class that identifies all embedPlayers: |
342 | | - $( swapPlayerElement ).addClass( 'mwEmbedPlayer' ); |
343 | | - |
344 | | - // Get properties / methods from playerInterface: |
345 | | - for ( var method in playerInterface ) { |
346 | | - if ( method != 'readyState' ) { // readyState crashes IE ( don't include ) |
347 | | - swapPlayerElement[ method ] = playerInterface[ method ]; |
348 | | - } |
349 | | - } |
350 | | - // Check if we are using native controls or Persistent player ( should keep the video embed around ) |
351 | | - if( playerInterface.useNativePlayerControls() || playerInterface.isPersistentNativePlayer() ) { |
352 | | - $( targetElement ) |
353 | | - .attr( 'id', playerInterface.pid ) |
354 | | - .addClass( 'nativeEmbedPlayerPid' ) |
355 | | - .show() |
356 | | - .after( |
357 | | - $( swapPlayerElement ).css( 'display', 'none' ) |
358 | | - ); |
359 | | - |
360 | | - } else { |
361 | | - $( targetElement ).replaceWith( swapPlayerElement ); |
362 | | - } |
363 | | - |
364 | | - |
365 | | - // Set swapPlayerElement has height / width set and set to loading: |
366 | | - $( swapPlayerElement ).css( { |
367 | | - 'width' : playerInterface.width + 'px', |
368 | | - 'height' : playerInterface.height + 'px' |
369 | | - } ); |
370 | | - |
371 | | - // If we don't already have a loadSpiner add one: |
372 | | - if( $('#loadingSpinner_' + playerInterface.id ).length == 0 && !$.browser.mozilla ){ |
373 | | - if( playerInterface.useNativePlayerControls() || playerInterface.isPersistentNativePlayer() ) { |
374 | | - var $spinner = $( targetElement ) |
375 | | - .getAbsoluteOverlaySpinner(); |
376 | | - }else{ |
377 | | - var $spinner = $( swapPlayerElement ).getAbsoluteOverlaySpinner(); |
378 | | - } |
379 | | - $spinner.attr('id', 'loadingSpinner_' + playerInterface.id ); |
380 | | - } |
381 | | - return swapPlayerElement; |
382 | | - }; |
383 | | - |
384 | | - // Add a loader for <div> embed player rewrites: |
385 | | - $( playerSelect ).each( function( index, playerElement) { |
386 | | - |
387 | | - // Make sure the playerElement has an id: |
388 | | - if( !$( playerElement ).attr('id') ){ |
389 | | - $( playerElement ).attr( "id", 'mwe_v' + ( index ) ); |
390 | | - } |
391 | | - |
392 | | - // If we are dynamically embedding on a "div" check if we can |
393 | | - // add a poster image behind the loader: |
394 | | - if( playerElement.nodeName.toLowerCase() == 'div' |
395 | | - && ( attributes.poster || $(playerElement).attr( 'poster' ) ) ){ |
396 | | - var posterSrc = ( attributes.poster ) ? attributes.poster : $(playerElement).attr( 'poster' ); |
397 | | - |
398 | | - // Set image size: |
399 | | - var width = $( playerElement ).width(); |
400 | | - var height = $( playerElement ).height(); |
401 | | - if( !width ){ |
402 | | - var width = ( attributes.width ) ? attributes.width : '100%'; |
403 | | - } |
404 | | - if( !height ){ |
405 | | - var height = ( attributes.height ) ? attributes.height : '100%'; |
406 | | - } |
407 | | - |
408 | | - mw.log('EmbedPlayer:: set loading background: ' + posterSrc); |
409 | | - $( playerElement ).append( |
410 | | - $( '<img />' ) |
411 | | - .attr( 'src', posterSrc) |
412 | | - .css({ |
413 | | - 'position' : 'absolute', |
414 | | - 'width' : width, |
415 | | - 'height' : height |
416 | | - }) |
417 | | - ); |
418 | | - } |
419 | | - }); |
420 | | - |
421 | | - // deprecated EmbedPlayerManagerReady event ( should remove ) |
422 | | - $( mw ).trigger( 'EmbedPlayerManagerReady' ); |
423 | | - |
424 | | - // Make sure we have user preference setup for setting preferences on video selection |
425 | | - var addedToPlayerManager = false; |
426 | | - mw.log("EmbedPlayer:: do: " + $( playerSelect ).length + ' players '); |
427 | | - |
428 | | - // Add each selected element to the player manager: |
429 | | - $( playerSelect ).each( function( index, playerElement) { |
430 | | - // Make sure the video tag was not generated by our library: |
431 | | - if( $( playerElement ).hasClass( 'nativeEmbedPlayerPid' ) ){ |
432 | | - $('#loadingSpinner_' + $( playerElement ).attr('id') ).remove(); |
433 | | - mw.log( 'EmbedPlayer::$.embedPlayer skip embedPlayer gennerated video: ' + playerElement ); |
434 | | - } else { |
435 | | - addedToPlayerManager = true; |
436 | | - // Add the player |
437 | | - addPlayerElement( playerElement ); |
438 | | - } |
439 | | - }); |
440 | | - if( addedToPlayerManager ){ |
441 | | - if( callback ){ |
442 | | - $( mw ).bind( "playersReadyEvent", callback ); |
443 | | - } |
444 | | - } else { |
445 | | - // Run the callback directly if no players were added |
446 | | - if( callback ){ |
447 | | - callback(); |
448 | | - } |
449 | | - } |
450 | | -}; |
451 | | - |
452 | | - |
453 | | -/** |
454 | 129 | * Base embedPlayer object |
455 | 130 | * |
456 | 131 | * @param {Element} |
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.processEmbedPlayers.js |
— | — | @@ -0,0 +1,323 @@ |
| 2 | +/** |
| 3 | + * Selector based embedPlayer processing |
| 4 | + * |
| 5 | + * @param {Function=} |
| 6 | + * callback Optional Function to be called once video interfaces |
| 7 | + * are ready |
| 8 | + * |
| 9 | + */ |
| 10 | +mw.processEmbedPlayers = function( playerSelect, callback ) { |
| 11 | + mw.log( 'EmbedPlayer:: processEmbedPlayers' ); |
| 12 | + |
| 13 | + // Check if the selected player set is ready if ready issue the parent callback |
| 14 | + var areSelectedPlayersReady = function(){ |
| 15 | + var playersLoaded = true; |
| 16 | + $(playerSelect).each(function(inx, player){ |
| 17 | + if( ! $( player ).get(0).doneLoading ){ |
| 18 | + playersLoaded = false; |
| 19 | + return false; |
| 20 | + } |
| 21 | + }) |
| 22 | + if( playersLoaded ){ |
| 23 | + if( callback ) |
| 24 | + callback(); |
| 25 | + } |
| 26 | + } |
| 27 | + |
| 28 | + /** |
| 29 | + * Adds a player element for the embedPlayer to rewrite |
| 30 | + * |
| 31 | + * uses embedPlayer interface on audio / video elements uses mvPlayList |
| 32 | + * interface on playlist elements |
| 33 | + * |
| 34 | + * Once a player interface is established the following chain of functions |
| 35 | + * are called; |
| 36 | + * |
| 37 | + * _this.checkPlayerSources() |
| 38 | + * _this.setupSourcePlayer() |
| 39 | + * _this.inheritEmbedPlayer() |
| 40 | + * _this.selectedPlayer.load() |
| 41 | + * _this.showPlayer() |
| 42 | + * |
| 43 | + * @param {Element} |
| 44 | + * playerElement DOM element to be swapped |
| 45 | + * @param {Object} |
| 46 | + * [Optional] attributes Extra attributes to apply to the player |
| 47 | + * interface |
| 48 | + */ |
| 49 | + var addPlayerElement = function( playerElement ) { |
| 50 | + var _this = this; |
| 51 | + mw.log('EmbedPlayer:: addElement:: ' + playerElement.id ); |
| 52 | + |
| 53 | + |
| 54 | + // Be sure to "stop" the target ( Firefox 3x keeps playing |
| 55 | + // the video even though its been removed from the DOM ) |
| 56 | + if( playerElement.pause ){ |
| 57 | + playerElement.pause(); |
| 58 | + } |
| 59 | + |
| 60 | + // Allow modules to override the wait for metadata flag: |
| 61 | + $( mw ).trigger( 'checkPlayerWaitForMetaData', playerElement ); |
| 62 | + |
| 63 | + // DOM *could* load height, width and duration eventually, in some browsers |
| 64 | + // By default, don't bother waiting for this. |
| 65 | + var waitForMeta = false; |
| 66 | + |
| 67 | + // if a plugin has told us not to waitForMeta, don't |
| 68 | + if ( playerElement.waitForMeta !== false ) { |
| 69 | + // Check if we should wait for metadata, after all |
| 70 | + waitForMeta = waitForMetaCheck( playerElement ); |
| 71 | + } |
| 72 | + |
| 73 | + var ranPlayerSwapFlag = false; |
| 74 | + |
| 75 | + // Local callback to runPlayer swap once playerElement has metadata |
| 76 | + function runPlayerSwap() { |
| 77 | + // Don't run player swap twice |
| 78 | + if( ranPlayerSwapFlag ){ |
| 79 | + return ; |
| 80 | + } |
| 81 | + ranPlayerSwapFlag = true; |
| 82 | + mw.log("EmbedPlayer::runPlayerSwap::" + $( playerElement ).attr('id') ); |
| 83 | + |
| 84 | + var playerInterface = new mw.EmbedPlayer( playerElement ); |
| 85 | + var swapPlayer = swapEmbedPlayerElement( playerElement, playerInterface ); |
| 86 | + |
| 87 | + // Trigger the EmbedPlayerNewPlayer for embedPlayer interface |
| 88 | + mw.log("EmbedPlayer::EmbedPlayerNewPlayer:trigger " + playerInterface.id ); |
| 89 | + |
| 90 | + // TODO: (from review) $( '#' + playerInterface.id ).get(0) is, theoreticaly, the same as swapPlayer and they might be interchangeable. |
| 91 | + $( mw ).trigger ( 'EmbedPlayerNewPlayer', $( '#' + playerInterface.id ).get(0) ); |
| 92 | + |
| 93 | + // Add a player ready binding: |
| 94 | + $( '#' + playerInterface.id ).bind( 'playerReady', areSelectedPlayersReady ); |
| 95 | + |
| 96 | + // Issue the checkPlayerSources call to the new player |
| 97 | + // interface: make sure to use the element that is in the DOM: |
| 98 | + // TODO: (from review) should be same as swapPlayer? |
| 99 | + $( '#' + playerInterface.id ).get(0).checkPlayerSources(); |
| 100 | + |
| 101 | + } |
| 102 | + |
| 103 | + if( waitForMeta && mw.getConfig('EmbedPlayer.WaitForMeta' ) ) { |
| 104 | + mw.log('EmbedPlayer::WaitForMeta ( video missing height (' + |
| 105 | + $( playerElement ).attr('height') + '), width (' + |
| 106 | + $( playerElement ).attr('width') + ') or duration: ' + |
| 107 | + $( playerElement ).attr('duration') |
| 108 | + ); |
| 109 | + $( playerElement ).bind("loadedmetadata", runPlayerSwap ); |
| 110 | + |
| 111 | + // Time-out of 5 seconds ( maybe still playable but no timely |
| 112 | + // metadata ) |
| 113 | + setTimeout( runPlayerSwap, 5000 ); |
| 114 | + return ; |
| 115 | + } else { |
| 116 | + runPlayerSwap(); |
| 117 | + return ; |
| 118 | + } |
| 119 | + }; |
| 120 | + |
| 121 | + /** |
| 122 | + * Check if we should wait for metadata. |
| 123 | + * |
| 124 | + * @return true if the size is "likely" to be updated by waiting for metadata |
| 125 | + * false if the size has been set via an attribute or is already loaded |
| 126 | + */ |
| 127 | + var waitForMetaCheck = function( playerElement ){ |
| 128 | + var waitForMeta = false; |
| 129 | + |
| 130 | + // Don't wait for metadata for non html5 media elements |
| 131 | + if( !playerElement ){ |
| 132 | + return false; |
| 133 | + } |
| 134 | + if( !playerElement.tagName || ( playerElement.tagName.toLowerCase() != 'audio' && playerElement.tagName.toLowerCase() != 'video' ) ){ |
| 135 | + return false; |
| 136 | + } |
| 137 | + // If we don't have a native player don't wait for metadata |
| 138 | + if( !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'oggNative') && |
| 139 | + !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'webmNative') && |
| 140 | + !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'h264Native' ) ) |
| 141 | + { |
| 142 | + return false; |
| 143 | + } |
| 144 | + |
| 145 | + |
| 146 | + var width = $( playerElement ).css( 'width' ); |
| 147 | + var height = $( playerElement ).css( 'height' ); |
| 148 | + |
| 149 | + // Css video defaults ( firefox ) |
| 150 | + if( $( playerElement ).css( 'width' ) == '300px' && |
| 151 | + $( playerElement ).css( 'height' ) == '150px' |
| 152 | + ){ |
| 153 | + waitForMeta = true; |
| 154 | + } else { |
| 155 | + // Check if we should wait for duration: |
| 156 | + if( $( playerElement ).attr( 'duration') || |
| 157 | + $( playerElement ).attr('data-durationhint') |
| 158 | + ){ |
| 159 | + // height, width and duration set; do not wait for meta data: |
| 160 | + return false; |
| 161 | + } else { |
| 162 | + waitForMeta = true; |
| 163 | + } |
| 164 | + } |
| 165 | + |
| 166 | + // Firefox ~ sometimes~ gives -1 for unloaded media |
| 167 | + if ( $(playerElement).attr( 'width' ) == -1 || $(playerElement).attr( 'height' ) == -1 ) { |
| 168 | + waitForMeta = true; |
| 169 | + } |
| 170 | + |
| 171 | + // Google Chrome / safari gives 0 width height for unloaded media |
| 172 | + if( $(playerElement).attr( 'width' ) === 0 || |
| 173 | + $(playerElement).attr( 'height' ) === 0 |
| 174 | + ) { |
| 175 | + waitForMeta = true; |
| 176 | + } |
| 177 | + |
| 178 | + // Firefox default width height is ~sometimes~ 150 / 300 |
| 179 | + if( this.height == 150 && this.width == 300 ){ |
| 180 | + waitForMeta = true; |
| 181 | + } |
| 182 | + |
| 183 | + // Make sure we have a src attribute or source child |
| 184 | + // ( i.e not a video tag to be dynamically populated or looked up from |
| 185 | + // xml resource description ) |
| 186 | + if( waitForMeta && |
| 187 | + ( |
| 188 | + $( playerElement ).attr('src') || |
| 189 | + $( playerElement ).find("source[src]").length !== 0 |
| 190 | + ) |
| 191 | + ) { |
| 192 | + // Detect src type ( if no type set ) |
| 193 | + return true; |
| 194 | + } else { |
| 195 | + // playerElement is not likely to update its meta data ( no src ) |
| 196 | + return false; |
| 197 | + } |
| 198 | + }; |
| 199 | + |
| 200 | + /** |
| 201 | + * swapEmbedPlayerElement |
| 202 | + * |
| 203 | + * Takes a video element as input and swaps it out with an embed player interface |
| 204 | + * |
| 205 | + * @param {Element} |
| 206 | + * targetElement Element to be swapped |
| 207 | + * @param {Object} |
| 208 | + * playerInterface Interface to swap into the target element |
| 209 | + */ |
| 210 | + var swapEmbedPlayerElement = function( targetElement, playerInterface ) { |
| 211 | + mw.log( 'EmbedPlayer::swapEmbedPlayerElement: ' + targetElement.id ); |
| 212 | + // Create a new element to swap the player interface into |
| 213 | + var swapPlayerElement = document.createElement('div'); |
| 214 | + |
| 215 | + // Add a class that identifies all embedPlayers: |
| 216 | + $( swapPlayerElement ).addClass( 'mwEmbedPlayer' ); |
| 217 | + |
| 218 | + // Get properties / methods from playerInterface: |
| 219 | + for ( var method in playerInterface ) { |
| 220 | + if ( method != 'readyState' ) { // readyState crashes IE ( don't include ) |
| 221 | + swapPlayerElement[ method ] = playerInterface[ method ]; |
| 222 | + } |
| 223 | + } |
| 224 | + // Check if we are using native controls or Persistent player ( should keep the video embed around ) |
| 225 | + if( playerInterface.useNativePlayerControls() || playerInterface.isPersistentNativePlayer() ) { |
| 226 | + $( targetElement ) |
| 227 | + .attr( 'id', playerInterface.pid ) |
| 228 | + .addClass( 'nativeEmbedPlayerPid' ) |
| 229 | + .show() |
| 230 | + .after( |
| 231 | + $( swapPlayerElement ).css( 'display', 'none' ) |
| 232 | + ); |
| 233 | + |
| 234 | + } else { |
| 235 | + $( targetElement ).replaceWith( swapPlayerElement ); |
| 236 | + } |
| 237 | + |
| 238 | + |
| 239 | + // Set swapPlayerElement has height / width set and set to loading: |
| 240 | + $( swapPlayerElement ).css( { |
| 241 | + 'width' : playerInterface.width + 'px', |
| 242 | + 'height' : playerInterface.height + 'px' |
| 243 | + } ); |
| 244 | + |
| 245 | + // If we don't already have a loadSpiner add one: |
| 246 | + if( $('#loadingSpinner_' + playerInterface.id ).length == 0 && !$.browser.mozilla ){ |
| 247 | + if( playerInterface.useNativePlayerControls() || playerInterface.isPersistentNativePlayer() ) { |
| 248 | + var $spinner = $( targetElement ) |
| 249 | + .getAbsoluteOverlaySpinner(); |
| 250 | + }else{ |
| 251 | + var $spinner = $( swapPlayerElement ).getAbsoluteOverlaySpinner(); |
| 252 | + } |
| 253 | + $spinner.attr('id', 'loadingSpinner_' + playerInterface.id ); |
| 254 | + } |
| 255 | + return swapPlayerElement; |
| 256 | + }; |
| 257 | + |
| 258 | + // Add a loader for <div> embed player rewrites: |
| 259 | + $( playerSelect ).each( function( index, playerElement) { |
| 260 | + |
| 261 | + // Make sure the playerElement has an id: |
| 262 | + if( !$( playerElement ).attr('id') ){ |
| 263 | + $( playerElement ).attr( "id", 'mwe_v' + ( index ) ); |
| 264 | + } |
| 265 | + |
| 266 | + // If we are dynamically embedding on a "div" check if we can |
| 267 | + // add a poster image behind the loader: |
| 268 | + if( playerElement.nodeName.toLowerCase() == 'div' |
| 269 | + && ( attributes.poster || $(playerElement).attr( 'poster' ) ) ){ |
| 270 | + var posterSrc = ( attributes.poster ) ? attributes.poster : $(playerElement).attr( 'poster' ); |
| 271 | + |
| 272 | + // Set image size: |
| 273 | + var width = $( playerElement ).width(); |
| 274 | + var height = $( playerElement ).height(); |
| 275 | + if( !width ){ |
| 276 | + var width = ( attributes.width ) ? attributes.width : '100%'; |
| 277 | + } |
| 278 | + if( !height ){ |
| 279 | + var height = ( attributes.height ) ? attributes.height : '100%'; |
| 280 | + } |
| 281 | + |
| 282 | + mw.log('EmbedPlayer:: set loading background: ' + posterSrc); |
| 283 | + $( playerElement ).append( |
| 284 | + $( '<img />' ) |
| 285 | + .attr( 'src', posterSrc) |
| 286 | + .css({ |
| 287 | + 'position' : 'absolute', |
| 288 | + 'width' : width, |
| 289 | + 'height' : height |
| 290 | + }) |
| 291 | + ); |
| 292 | + } |
| 293 | + }); |
| 294 | + |
| 295 | + // deprecated EmbedPlayerManagerReady event ( should remove ) |
| 296 | + $( mw ).trigger( 'EmbedPlayerManagerReady' ); |
| 297 | + |
| 298 | + // Make sure we have user preference setup for setting preferences on video selection |
| 299 | + var addedToPlayerManager = false; |
| 300 | + mw.log("EmbedPlayer:: do: " + $( playerSelect ).length + ' players '); |
| 301 | + |
| 302 | + // Add each selected element to the player manager: |
| 303 | + $( playerSelect ).each( function( index, playerElement) { |
| 304 | + // Make sure the video tag was not generated by our library: |
| 305 | + if( $( playerElement ).hasClass( 'nativeEmbedPlayerPid' ) ){ |
| 306 | + $('#loadingSpinner_' + $( playerElement ).attr('id') ).remove(); |
| 307 | + mw.log( 'EmbedPlayer::$.embedPlayer skip embedPlayer gennerated video: ' + playerElement ); |
| 308 | + } else { |
| 309 | + addedToPlayerManager = true; |
| 310 | + // Add the player |
| 311 | + addPlayerElement( playerElement ); |
| 312 | + } |
| 313 | + }); |
| 314 | + if( addedToPlayerManager ){ |
| 315 | + if( callback ){ |
| 316 | + $( mw ).bind( "playersReadyEvent", callback ); |
| 317 | + } |
| 318 | + } else { |
| 319 | + // Run the callback directly if no players were added |
| 320 | + if( callback ){ |
| 321 | + callback(); |
| 322 | + } |
| 323 | + } |
| 324 | +}; |
\ No newline at end of file |
Property changes on: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.processEmbedPlayers.js |
___________________________________________________________________ |
Added: svn:mime-type |
1 | 325 | + text/plain |
Index: trunk/extensions/TimedMediaHandler/resources/mw.MediaWikiPlayer.loader.js |
— | — | @@ -1,4 +1,3 @@ |
2 | | -// Wrap in mediaWiki |
3 | 2 | ( function( mw, $ ) { |
4 | 3 | // Add MediaWikiSupportPlayer dependency on players with a mediaWiki title |
5 | 4 | $( mw ).bind( 'EmbedPlayerUpdateDependencies', function( event, embedPlayer, dependencySet ){ |