Index: branches/MwEmbedStandAlone/mwEmbed.js |
— | — | @@ -1216,7 +1216,6 @@ |
1217 | 1217 | * string String to output to console |
1218 | 1218 | */ |
1219 | 1219 | mw.log = function( string ) { |
1220 | | - |
1221 | 1220 | // Add any prepend debug strings if necessary |
1222 | 1221 | if ( mw.getConfig( 'pre-append-log' ) ){ |
1223 | 1222 | string = mw.getConfig( 'pre-append-log' ) + string; |
— | — | @@ -1227,17 +1226,18 @@ |
1228 | 1227 | } else { |
1229 | 1228 | /** |
1230 | 1229 | * Old IE and non-Firebug debug: ( commented out for now ) |
1231 | | - */ |
1232 | | - /* |
1233 | | - * var log_elm = document.getElementById('mv_js_log'); if(!log_elm) { |
1234 | | - * document.getElementsByTagName("body")[0].innerHTML = |
1235 | | - * document.getElementsByTagName("body")[0].innerHTML + '<div |
1236 | | - * style="position:absolute;z-index:500;bottom:0px;left:0px;right:0px;height:200px;">'+ '<textarea |
1237 | | - * id="mv_js_log" cols="120" rows="12"></textarea>'+ '</div>'; |
1238 | | - * |
1239 | | - * var log_elm = document.getElementById('mv_js_log'); } if(log_elm) { |
1240 | | - * log_elm.value+=string+"\n"; } |
1241 | | - */ |
| 1230 | + */ |
| 1231 | + /*var log_elm = document.getElementById('mv_js_log'); |
| 1232 | + if(!log_elm) { |
| 1233 | + document.getElementsByTagName("body")[0].innerHTML += '<div ' + |
| 1234 | + 'style="position:absolute;z-index:500;bottom:0px;left:0px;right:0px;height:200px;">' + |
| 1235 | + '<textarea id="mv_js_log" cols="120" rows="12"></textarea>' + |
| 1236 | + '</div>'; |
| 1237 | + } |
| 1238 | + var log_elm = document.getElementById('mv_js_log'); |
| 1239 | + if(log_elm) { |
| 1240 | + log_elm.value+=string+"\n"; |
| 1241 | + }*/ |
1242 | 1242 | } |
1243 | 1243 | } |
1244 | 1244 | |
— | — | @@ -2417,7 +2417,7 @@ |
2418 | 2418 | /** |
2419 | 2419 | * Set DOM-ready call We copy jQuery( document ).ready here since sometimes |
2420 | 2420 | * mwEmbed.js is included without jQuery and we need our own "ready" system so |
2421 | | - * that mwEmbed interfaces can support async built out and the inclution of |
| 2421 | + * that mwEmbed interfaces can support async built out and the include of |
2422 | 2422 | * jQuery. |
2423 | 2423 | */ |
2424 | 2424 | var mwDomIsReady = false; |
Index: branches/MwEmbedStandAlone/tests/selenium_tests/audio-player-menu.html |
— | — | @@ -18,7 +18,7 @@ |
19 | 19 | </tr> |
20 | 20 | <tr> |
21 | 21 | <td>waitForElementPresent</td> |
22 | | - <td>//div[@class='interface_wrap k-player']</td> |
| 22 | + <td>//div[@class='mwplayer_interface k-player']</td> |
23 | 23 | <td>9000</td> |
24 | 24 | </tr> |
25 | 25 | <tr> |
Index: branches/MwEmbedStandAlone/tests/selenium_tests/player-themable-display.html |
— | — | @@ -18,12 +18,12 @@ |
19 | 19 | </tr> |
20 | 20 | <tr> |
21 | 21 | <td>waitForElementPresent</td> |
22 | | - <td>//div[@class="interface_wrap k-player"]</td> |
| 22 | + <td>//div[@class="mwplayer_interface k-player"]</td> |
23 | 23 | <td>9000</td> |
24 | 24 | </tr> |
25 | 25 | <tr> |
26 | 26 | <td>waitForElementPresent</td> |
27 | | - <td>//div[@class="interface_wrap mv-player"]</td> |
| 27 | + <td>//div[@class="mwplayer_interface mv-player"]</td> |
28 | 28 | <td>9000</td> |
29 | 29 | </tr> |
30 | 30 | <tr> |
Index: branches/MwEmbedStandAlone/tests/selenium_tests/EmbedPlayerLoadsTest.php |
— | — | @@ -20,8 +20,8 @@ |
21 | 21 | |
22 | 22 | $this->waitForPageToLoad(10000); |
23 | 23 | |
24 | | - $this->isElementPresent("//div[@class='interface_wrap k-player']", 10000); |
25 | | - $this->isElementPresent("//div[@class='interface_wrap mv-player']", 10000); |
| 24 | + $this->isElementPresent("//div[@class='mwplayer_interface k-player']", 10000); |
| 25 | + $this->isElementPresent("//div[@class='mwplayer_interface mv-player']", 10000); |
26 | 26 | $this->isElementPresent("//div[@class='ui-state-default play-btn-large']", 10000); |
27 | 27 | |
28 | 28 | } |
Index: branches/MwEmbedStandAlone/tests/selenium_tests/audio-player-playback-progress.html |
— | — | @@ -18,7 +18,7 @@ |
19 | 19 | </tr> |
20 | 20 | <tr> |
21 | 21 | <td>waitForElementPresent</td> |
22 | | - <td>//div[@class='interface_wrap k-player']</td> |
| 22 | + <td>//div[@class='mwplayer_interface k-player']</td> |
23 | 23 | <td>9000</td> |
24 | 24 | </tr> |
25 | 25 | <tr> |
Index: branches/MwEmbedStandAlone/ResourceLoader.php |
— | — | @@ -101,7 +101,7 @@ |
102 | 102 | try { |
103 | 103 | NamedResourceLoader::loadResourcePaths(); |
104 | 104 | } catch( Exception $e ) { |
105 | | - $this->errorMsg .= $e->getMessage() ; |
| 105 | + $this->errorMsg .= "loadResourcePaths:" . $e->getMessage() ; |
106 | 106 | } |
107 | 107 | |
108 | 108 | // Reset the requestKey: |
— | — | @@ -182,7 +182,7 @@ |
183 | 183 | if ( $wgUseFileCache && !$this->debug ) { |
184 | 184 | $status = $this->sFileCache->saveToFileCache( $this->output ); |
185 | 185 | if ( $status !== true ) { |
186 | | - $this->errorMsg .= $status; |
| 186 | + $this->errorMsg .= "Could not save file to cache::" . $status; |
187 | 187 | } |
188 | 188 | } |
189 | 189 | |
— | — | @@ -190,7 +190,7 @@ |
191 | 191 | if ( $this->errorMsg != '' ) { |
192 | 192 | //just set the content type (don't send cache header) |
193 | 193 | header( 'Content-Type: text/javascript' ); |
194 | | - echo 'if(console.log)console.log(\'Error With ScriptLoader ::' . |
| 194 | + echo 'if(console.log)console.log(\'Error With ResourceLoader ::' . |
195 | 195 | str_replace( "\n", '\'+"\n"+' . "\n'", |
196 | 196 | xml::escapeJsString( $this->errorMsg ) |
197 | 197 | ) . '\');'."\n"; |
— | — | @@ -728,7 +728,7 @@ |
729 | 729 | try { |
730 | 730 | NamedResourceLoader::loadResourcePaths(); |
731 | 731 | } catch( Exception $e ) { |
732 | | - $this->errorMsg .= $e->getMessage() ; |
| 732 | + $this->errorMsg .= "getPathFromClass: " . $e->getMessage() ; |
733 | 733 | } |
734 | 734 | |
735 | 735 | if ( isset( $wgResourceLoaderNamedPaths[ $reqClass ] ) ) { |
Index: branches/MwEmbedStandAlone/includes/NamedResourceLoader.php |
— | — | @@ -17,7 +17,7 @@ |
18 | 18 | private static $combinedLoadersJs = ''; |
19 | 19 | |
20 | 20 | // Reg Exp that supports extracting classes from loaders |
21 | | - private static $classReplaceExp = '/mw\.addResourcePaths\s*\(\s*{(.*)}\s*\)\s*\;/siU'; |
| 21 | + private static $classReplaceExp = '/mw\.addResourcePaths\s*\(\s*{(.*)}\s*\)\s*[\;\n]/siU'; |
22 | 22 | |
23 | 23 | // Flag to specify if the javascript resource paths have been loaded. |
24 | 24 | private static $classesLoaded = false; |
Index: branches/MwEmbedStandAlone/modules/Playlist/loader.js |
— | — | @@ -30,6 +30,7 @@ |
31 | 31 | |
32 | 32 | // Module loader ( right now its just a stub for mw.MediaRss ) |
33 | 33 | mw.addModuleLoader( 'Playlist', [ "mw.Playlist", "mw.PlaylistHandlerMediaRss" ] ); |
| 34 | + |
34 | 35 | |
35 | 36 | } )( window.mw ); |
36 | 37 | |
Index: branches/MwEmbedStandAlone/modules/Playlist/mw.Playlist.js |
— | — | @@ -31,9 +31,17 @@ |
32 | 32 | } |
33 | 33 | |
34 | 34 | // Set the sourceHandler if provided |
35 | | - if( options.sourceHandler ) |
| 35 | + if( options.sourceHandler ) { |
36 | 36 | this.sourceHandler = options.sourceHandler; |
| 37 | + } |
37 | 38 | |
| 39 | + |
| 40 | + // Set binding to disable "waitForMeta" for playlist items ( we know the size and length ) |
| 41 | + $j( mw ).bind( 'addElementWaitForMetaEvent', function(even, waitForMetaObject ){ |
| 42 | + if( $j( waitForMetaObject[ 'playerElement' ] ).hasClass( 'mwPlaylist') ){ |
| 43 | + waitForMetaObject[ 'waitForMeta' ] = false; |
| 44 | + } |
| 45 | + }); |
38 | 46 | |
39 | 47 | this.type = ( options.type ) ? |
40 | 48 | options.type: |
— | — | @@ -102,6 +110,7 @@ |
103 | 111 | |
104 | 112 | // Add the player |
105 | 113 | _this.updatePlayer( _this.clipIndex, function(){ |
| 114 | + |
106 | 115 | // Update the list height ( vertical layout ) |
107 | 116 | if( _this.layout == 'vertical' ){ |
108 | 117 | var targetListHeight = ( $j( _this.target ).height() - $j( _this.target + ' .media-rss-video-player' ).height() ); |
— | — | @@ -170,6 +179,7 @@ |
171 | 180 | |
172 | 181 | // Build and output the title |
173 | 182 | var $title = $j('<div />' ) |
| 183 | + .addClass( 'playlist-title') |
174 | 184 | .css( { |
175 | 185 | 'height' : _this.titleHeight, |
176 | 186 | 'font-size' : '85%', |
— | — | @@ -178,14 +188,10 @@ |
179 | 189 | .text( |
180 | 190 | _this.sourceHandler.getClipTitle( clipIndex ) |
181 | 191 | ) |
182 | | - .addClass( 'ui-state-default ui-widget-header' ) |
183 | | - |
184 | | - $j( _this.target + ' .media-rss-video-player' ) |
185 | | - .empty() |
186 | | - .append( |
187 | | - $title |
188 | | - ); |
| 192 | + .addClass( 'ui-state-default ui-widget-header' ) |
189 | 193 | |
| 194 | + $j( _this.target + ' .media-rss-video-player' ).find('.playlist-title').remove( ); |
| 195 | + $j( _this.target + ' .media-rss-video-player' ).prepend( $title ); |
190 | 196 | |
191 | 197 | // Update the player list if present: |
192 | 198 | $j( _this.target + ' .clipItemBlock') |
— | — | @@ -200,47 +206,79 @@ |
201 | 207 | 'id' : 'mrss_' + this.id + '_' + clipIndex, |
202 | 208 | 'poster' : _this.sourceHandler.getClipPoster( clipIndex ) |
203 | 209 | }) |
| 210 | + .addClass( 'mwPlaylist' ) |
204 | 211 | .css( |
205 | 212 | playerSize |
206 | 213 | ) |
207 | 214 | // Add custom attributes: |
208 | 215 | .attr( _this.sourceHandler.getCustomClipAttributes( clipIndex ) ); |
209 | 216 | |
210 | | - // if we don't have an api based lookup ( kentryid ) lookup the sources from the |
211 | | - // playlist provider: |
212 | | - if( ! $video.attr( 'kentryid' ) ){ |
213 | | - this.sourceHandler.getClipSources( clipIndex, function( clipSources ){ |
214 | | - |
215 | | - if( clipSources ){ |
216 | | - for( var i =0; i < clipSources.length; i++ ){ |
217 | | - var $source = $j('<source />') |
218 | | - .attr( clipSources[i] ); |
219 | | - $video.append( $source ); |
220 | | - } |
| 217 | + // lookup the sources from the playlist provider: |
| 218 | + this.sourceHandler.getClipSources( clipIndex, function( clipSources ){ |
| 219 | + if( clipSources ){ |
| 220 | + for( var i =0; i < clipSources.length; i++ ){ |
| 221 | + var $source = $j('<source />') |
| 222 | + .attr( clipSources[i] ); |
| 223 | + $video.append( $source ); |
221 | 224 | } |
222 | | - _this.addVideoPlayer( $video , callback); |
223 | | - }); |
224 | | - } else { |
225 | | - this.addVideoPlayer( $video , callback); |
226 | | - } |
| 225 | + } |
| 226 | + _this.addVideoPlayer( $video , callback); |
| 227 | + }); |
227 | 228 | }, |
228 | 229 | |
229 | 230 | addVideoPlayer: function( $video , callback){ |
230 | 231 | var _this = this; |
231 | | - $j( _this.target + ' .media-rss-video-player' ).append( $video ); |
| 232 | + // If on mobile safari just swap the sources ( don't replace the video ) |
| 233 | + // ( mobile safari can't javascript start the video ) |
| 234 | + // see: http://developer.apple.com/iphone/search/search.php?simp=1&num=10&Search=html5+autoplay |
| 235 | + var addVideoPlayerToDom = true; |
| 236 | + if( mw.isMobileSafari() ){ |
| 237 | + // Check for a current video: |
| 238 | + var $inDomVideo = $j( _this.target + ' .media-rss-video-player video' ); |
| 239 | + if( $inDomVideo.length == 0 ){ |
| 240 | + addVideoPlayerToDom= true; |
| 241 | + } else { |
| 242 | + addVideoPlayerToDom = false; |
| 243 | + // Update the inDomVideo object: |
| 244 | + // NOTE: this hits a lot of internal stuff should ! |
| 245 | + // XXX Should refactor to use embedPlayer interfaces! |
| 246 | + var vidInterface = $j( _this.target + ' .media-rss-video-player' ).find('.mwplayer_interface div').get(0) |
| 247 | + vidInterface.id = $video.attr('id'); |
| 248 | + vidInterface.pid = 'pid_' + $video.attr('id'); |
| 249 | + vidInterface.duration = null; |
| 250 | + if( $video.attr('kentryid') ){ |
| 251 | + vidInterface.kentryid = $video.attr('kentryid'); |
| 252 | + } |
| 253 | + // Update the current video target source |
| 254 | + $inDomVideo.attr({ |
| 255 | + 'id' : 'pid_' + $video.attr('id'), |
| 256 | + 'src': $video.find( 'source').attr('src') |
| 257 | + }); |
| 258 | + |
| 259 | + } |
| 260 | + } else { |
| 261 | + // Remove the old video player ( non-mobile safari ) |
| 262 | + // xxx NOTE: need to check fullscreen support might be better to universally swap the src ) |
| 263 | + $j( _this.target + ' .media-rss-video-player' ).remove( 'video' ); |
| 264 | + } |
232 | 265 | |
| 266 | + if( addVideoPlayerToDom ) { |
| 267 | + // replace the video: |
| 268 | + $j( _this.target + ' .media-rss-video-player' ).append( $video ); |
| 269 | + } |
| 270 | + |
233 | 271 | // Update the video tag with the embedPlayer |
234 | 272 | $j.embedPlayers( function(){ |
235 | 273 | // Setup ondone playing binding to play next clip |
236 | | - $j( '#mrss_' + _this.id + '_' + _this.clipIndex ).bind( 'ended', function(event, onDoneActionObject ){ |
| 274 | + $j( '#mrss_' + _this.id + '_' + _this.clipIndex ).unbind('ended').bind( 'ended', function(event, onDoneActionObject ){ |
237 | 275 | // Play next clip |
238 | 276 | if( _this.clipIndex + 1 < _this.sourceHandler.getClipCount() ){ |
239 | 277 | // Update the onDone action object to not run the base control done: |
240 | 278 | onDoneActionObject.runBaseControlDone = false; |
241 | 279 | _this.clipIndex++; |
242 | 280 | |
243 | | - // ( if on ipad update the src and don't refresh ) |
244 | | - _this.updatePlayer( _this.clipIndex, function(){ |
| 281 | + // update the player and play the next clip |
| 282 | + _this.updatePlayer( _this.clipIndex, function(){ |
245 | 283 | _this.play(); |
246 | 284 | }) |
247 | 285 | |
— | — | @@ -249,8 +287,7 @@ |
250 | 288 | // Update the onDone action object to not run the base control done: |
251 | 289 | onDoneActionObject.runBaseControlDone = true; |
252 | 290 | } |
253 | | - }) |
254 | | - |
| 291 | + }) |
255 | 292 | // Run the callback if its set |
256 | 293 | if( callback ){ |
257 | 294 | callback(); |
— | — | @@ -340,8 +377,10 @@ |
341 | 378 | */ |
342 | 379 | play: function(){ |
343 | 380 | // Get the player and play: |
344 | | - var vid = $j( this.target + ' .media-rss-video-player .interface_wrap').children().get(0); |
345 | | - if( vid && vid.play ){ |
| 381 | + var vid = $j('#mrss_' + this.id + '_' + this.clipIndex ).get(0); |
| 382 | + //alert( 'play: '+ ) |
| 383 | + if( vid && vid.play ){ |
| 384 | + vid.load(); |
346 | 385 | vid.play(); |
347 | 386 | } |
348 | 387 | }, |
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBody.js |
— | — | @@ -50,13 +50,16 @@ |
51 | 51 | if( !$node.attr('id') |
52 | 52 | && !$node.attr( 'xml:id' ) |
53 | 53 | ){ |
| 54 | + var idString = _this.getNodeSmilType( $node ) + '_' + _this.idIndex; |
54 | 55 | // Make sure the id does not already exist ( should be a rare case ) |
55 | | - var idString = _this.getNodeSmilType( $node ) + '_' + _this.idIndex; |
56 | | - if( this.$dom.find( '#' + idString ).length != 0 ){ |
57 | | - idString+= '_' + Math.random(); |
| 56 | + while( this.$dom.find( '#' + idString ).length != 0 ){ |
| 57 | + _this.idIndex++; |
| 58 | + idString = _this.getNodeSmilType( $node ) + '_' + _this.idIndex; |
58 | 59 | } |
| 60 | + // Apply the unique id attribute |
59 | 61 | $node.attr('id', idString); |
60 | 62 | mw.log('SmilBody:: gave: ' + $node.get(0).nodeName + ' id: ' + $node.attr('id') ); |
| 63 | + // Increment the index: |
61 | 64 | _this.idIndex++; |
62 | 65 | } |
63 | 66 | |
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.Smil.js |
— | — | @@ -91,7 +91,7 @@ |
92 | 92 | this.$dom = $j( smilXmlString ); |
93 | 93 | |
94 | 94 | mw.log("Smil::loadFromString: loaded smil dom: " + this.$dom.length + "\n" + smilXmlString ); |
95 | | - |
| 95 | + /* |
96 | 96 | // Clear out the layout |
97 | 97 | this.layout = null; |
98 | 98 | |
— | — | @@ -103,10 +103,11 @@ |
104 | 104 | |
105 | 105 | // Clear out the "buffer" object |
106 | 106 | this.buffer = null; |
| 107 | + */ |
107 | 108 | }, |
108 | 109 | updateFromString: function( smilXmlString ){ |
109 | | - var tmpDom = $j( smilXmlString ); |
110 | | - // merge in xml changes? |
| 110 | + delete this.$dom; |
| 111 | + this.$dom = $j( smilXmlString ); |
111 | 112 | }, |
112 | 113 | /** |
113 | 114 | * Internal function to get the jQuery smil dom |
— | — | @@ -269,6 +270,7 @@ |
270 | 271 | } |
271 | 272 | return this.duration; |
272 | 273 | }, |
| 274 | + |
273 | 275 | removeById: function ( smilElementId ) { |
274 | 276 | var $smilElement = this.$dom.find( '#' + smilElementId ); |
275 | 277 | |
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBuffer.js |
— | — | @@ -403,7 +403,7 @@ |
404 | 404 | |
405 | 405 | var $vid = $j ( '#' + assetId); |
406 | 406 | var vid = $vid.get(0); |
407 | | - // Add the asset to the loading set |
| 407 | + // Add the asset to the loading set (if not there already ) |
408 | 408 | _this.addAssetLoading( $vid.attr('id' ) ); |
409 | 409 | var seekCallbackDone = false; |
410 | 410 | var runSeekCallback = function(){ |
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/loader.js |
— | — | @@ -54,7 +54,7 @@ |
55 | 55 | // "videojs" will include the source javascript and video tag to |
56 | 56 | // rewrite the player on the remote page DOM |
57 | 57 | // Video tag embedding is much more mash-up friendly but exposes |
58 | | - // the remote site to the mwEmbed js. |
| 58 | + // the remote site to the mwEmbed javascript and can be a xss issue. |
59 | 59 | "EmbedPlayer.ShareEmbedMode" : 'object', |
60 | 60 | |
61 | 61 | // Default player skin name |
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/mw.EmbedPlayer.js |
— | — | @@ -192,7 +192,7 @@ |
193 | 193 | * The base source attribute checks |
194 | 194 | * also see: http://dev.w3.org/html5/spec/Overview.html#the-source-element |
195 | 195 | */ |
196 | | -mw.setConfig( 'embedPlayerSourceAttributes', [ |
| 196 | +mw.setDefaultConfig( 'embedPlayerSourceAttributes', [ |
197 | 197 | // source id |
198 | 198 | 'id', |
199 | 199 | |
— | — | @@ -325,23 +325,29 @@ |
326 | 326 | // Run the global hooks that mw.playerManager is ready |
327 | 327 | mw.log( 'EmbedPlayer::trigger: EmbedPlayerManagerReady'); |
328 | 328 | $j( mw ).trigger( 'EmbedPlayerManagerReady' ); |
329 | | - } |
330 | | - |
331 | | - // Add the embedPlayer ready callback |
332 | | - if( typeof callback == 'function' ){ |
333 | | - mw.playerManager.addCallback( callback ); |
334 | | - } |
| 329 | + } |
| 330 | + var addedToPlayerManager = false; |
335 | 331 | // Make sure we have user preference setup ( for setting preferences on video selection ) |
336 | 332 | mw.setupUserConfig( function() { |
337 | 333 | // Add each selected element to the player manager: |
338 | 334 | $j( playerSelect ).each( function( index, playerElement) { |
339 | | - // Make sure the video tag was not generated by our own native player: |
| 335 | + // Make sure the video tag was not generated by our library: |
340 | 336 | if( $j( playerElement ).hasClass( 'nativeEmbedPlayerPid' ) ){ |
341 | | - mw.log( 'EmbedPlayer::$j.embedPlayer skip embedPlayer gennerated video: ' + playerElement ); |
| 337 | + mw.log( 'EmbedPlayer::$j.embedPlayer skip embedPlayer gennerated video: ' + playerElement ); |
342 | 338 | } else { |
| 339 | + addedToPlayerManager = true; |
| 340 | + // Add the embedPlayer ready callback |
| 341 | + mw.playerManager.addCallback( callback ); |
| 342 | + // Add the player |
343 | 343 | mw.playerManager.addElement( playerElement, attributes); |
344 | | - } |
345 | | - } ); |
| 344 | + } |
| 345 | + |
| 346 | + } ); |
| 347 | + // run the callback directly if no players were added to the playerManager |
| 348 | + if( !addedToPlayerManager && callback ){ |
| 349 | + callback(); |
| 350 | + } |
| 351 | + |
346 | 352 | }) |
347 | 353 | }; |
348 | 354 | |
— | — | @@ -376,7 +382,9 @@ |
377 | 383 | * @param {Function} callback Function to be called once players are ready |
378 | 384 | */ |
379 | 385 | addCallback: function( callback ) { |
380 | | - this.callbackFunctions.push( callback ); |
| 386 | + if( typeof callback == 'function' ){ |
| 387 | + this.callbackFunctions.push( callback ); |
| 388 | + } |
381 | 389 | }, |
382 | 390 | |
383 | 391 | /** |
— | — | @@ -477,8 +485,13 @@ |
478 | 486 | $j( '#' + playerInterface.id ).get(0).checkPlayerSources(); |
479 | 487 | } |
480 | 488 | |
481 | | - if( waitForMeta ) { |
482 | | - mw.log('EmbedPlayer::WaitForMeta ( video missing height (' + $j( playerElement ).attr('height') + '), width (' + $j( playerElement ).attr('width') + ') or duration' ); |
| 489 | + if( waitForMeta ) { |
| 490 | + mw.log('EmbedPlayer::WaitForMeta ( video missing height (' + |
| 491 | + $j( playerElement ).attr('height') + '), width (' + |
| 492 | + $j( playerElement ).attr('width') + ') or duration: ' + |
| 493 | + $j( playerElement ).attr('duration') |
| 494 | + ); |
| 495 | + |
483 | 496 | playerElement.removeEventListener( "loadedmetadata", runPlayerSwap, true ); |
484 | 497 | playerElement.addEventListener( "loadedmetadata", runPlayerSwap, true ); |
485 | 498 | |
— | — | @@ -655,7 +668,7 @@ |
656 | 669 | mw.log( "EmbedPlayer::All on-page players ready run playerMannager callbacks" ); |
657 | 670 | // Run queued functions |
658 | 671 | if( _this.callbackFunctions ) { |
659 | | - while ( _this.callbackFunctions.length ) { |
| 672 | + while ( _this.callbackFunctions.length ) { |
660 | 673 | _this.callbackFunctions.shift()(); |
661 | 674 | } |
662 | 675 | } |
— | — | @@ -2085,13 +2098,13 @@ |
2086 | 2099 | // Set-up the local controlBuilder instance: |
2087 | 2100 | this.controlBuilder = new mw.PlayerControlBuilder( this ); |
2088 | 2101 | var _this = this; |
2089 | | - // Make sure we have interface_wrap |
2090 | | - if( $j( this ).parent( '.interface_wrap' ).length == 0 ) { |
| 2102 | + // Make sure we have mwplayer_interface |
| 2103 | + if( $j( this ).parent( '.mwplayer_interface' ).length == 0 ) { |
2091 | 2104 | // Select "player" |
2092 | 2105 | $j( this ) |
2093 | 2106 | .wrap( |
2094 | 2107 | $j('<div>') |
2095 | | - .addClass( 'interface_wrap ' + this.controlBuilder.playerClass ) |
| 2108 | + .addClass( 'mwplayer_interface ' + this.controlBuilder.playerClass ) |
2096 | 2109 | .css({ |
2097 | 2110 | 'width' : parseInt( this.width ) + 'px', |
2098 | 2111 | 'height' : parseInt( this.height ) + 'px', |
— | — | @@ -2100,8 +2113,8 @@ |
2101 | 2114 | ) |
2102 | 2115 | } |
2103 | 2116 | |
2104 | | - //Set up local jQuery object reference to "interface_wrap" |
2105 | | - this.$interface = $j( this ).parent( '.interface_wrap' ); |
| 2117 | + //Set up local jQuery object reference to "mwplayer_interface" |
| 2118 | + this.$interface = $j( this ).parent( '.mwplayer_interface' ); |
2106 | 2119 | |
2107 | 2120 | // Update Thumbnail for the "player" |
2108 | 2121 | this.updatePosterHTML(); |
— | — | @@ -2810,7 +2823,7 @@ |
2811 | 2824 | this.preMuteVolume = this.volume; |
2812 | 2825 | var percent = 0; |
2813 | 2826 | } |
2814 | | - this.setVolume( percent ); |
| 2827 | + this.setVolume( percent ); |
2815 | 2828 | // Update the interface |
2816 | 2829 | this.setInterfaceVolume( percent ); |
2817 | 2830 | }, |
— | — | @@ -2963,8 +2976,8 @@ |
2964 | 2977 | this.checkForCurrentTimeSeek(); |
2965 | 2978 | |
2966 | 2979 | // Update currentTime via embedPlayer |
2967 | | - _this.currentTime = _this.getPlayerElementTime(); |
2968 | | - |
| 2980 | + _this.currentTime = _this.getPlayerElementTime(); |
| 2981 | + |
2969 | 2982 | // Update the previousTime ( so we can know if the user-javascript changed currentTime ) |
2970 | 2983 | _this.previousTime = _this.currentTime; |
2971 | 2984 | |
— | — | @@ -2984,7 +2997,9 @@ |
2985 | 2998 | // update the mute state from the player element |
2986 | 2999 | if( _this.muted != _this.getPlayerElementMuted() ){ |
2987 | 3000 | mw.log("monitor:: muted does not mach embed player" ); |
2988 | | - this.toggleMute(); |
| 3001 | + _this.toggleMute(); |
| 3002 | + // Make sure they match: |
| 3003 | + _this.muted = _this.getPlayerElementMuted(); |
2989 | 3004 | } |
2990 | 3005 | |
2991 | 3006 | //mw.log( 'Monitor:: ' + this.currentTime + ' duration: ' + ( parseInt( this.getDuration() ) + 1 ) + ' is seek: ' + this.seeking ); |
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/skins/mw.PlayerControlBuilder.js |
— | — | @@ -65,7 +65,7 @@ |
66 | 66 | this.embedPlayer = embedPlayer; |
67 | 67 | |
68 | 68 | // Check for skin overrides for controlBuilder |
69 | | - var skinClass = embedPlayer.skinName[0].toUpperCase() + embedPlayer.skinName.substr( 1 ); |
| 69 | + var skinClass = embedPlayer.skinName.substr(0,1).toUpperCase() + embedPlayer.skinName.substr( 1 ); |
70 | 70 | if ( mw['PlayerSkin' + skinClass ]) { |
71 | 71 | |
72 | 72 | // Clone as to not override prototype with the skin config |
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/mw.EmbedPlayerNative.js |
— | — | @@ -312,12 +312,12 @@ |
313 | 313 | * Get the embed player time |
314 | 314 | */ |
315 | 315 | getPlayerElementTime: function() { |
316 | | - var _this = this; |
| 316 | + var _this = this; |
317 | 317 | // Make sure we have .vid obj |
318 | 318 | this.getPlayerElement(); |
319 | 319 | |
320 | 320 | if ( !this.playerElement ) { |
321 | | - mw.log( 'could not find video embed: ' + this.id + ' stop monitor' ); |
| 321 | + mw.log( 'Error: mwEmbedPlayer::getPlayerElementTime: missing ' + this.id + ' stop monitor' ); |
322 | 322 | return false; |
323 | 323 | } |
324 | 324 | // Return the playerElement currentTime |
— | — | @@ -448,7 +448,7 @@ |
449 | 449 | /** |
450 | 450 | * Get /update the playerElement value |
451 | 451 | */ |
452 | | - getPlayerElement: function () { |
| 452 | + getPlayerElement: function () { |
453 | 453 | this.playerElement = $j( '#' + this.pid ).get( 0 ); |
454 | 454 | return this.playerElement; |
455 | 455 | }, |
— | — | @@ -519,8 +519,8 @@ |
520 | 520 | */ |
521 | 521 | onloadedmetadata: function() { |
522 | 522 | this.getPlayerElement(); |
523 | | - mw.log( 'f:onloadedmetadata metadata ready Update duration:' + this.playerElement.duration + ' old dur: ' + this.getDuration() ); |
524 | | - if ( ! isNaN( this.playerElement.duration ) ) { |
| 523 | + if ( this.playerElement && ! isNaN( this.playerElement.duration ) ) { |
| 524 | + mw.log( 'f:onloadedmetadata metadata ready Update duration:' + this.playerElement.duration + ' old dur: ' + this.getDuration() ); |
525 | 525 | this.duration = this.playerElement.duration; |
526 | 526 | } |
527 | 527 | |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.Sequencer.js |
— | — | @@ -96,17 +96,19 @@ |
97 | 97 | * Update the smil xml and then update the interface |
98 | 98 | */ |
99 | 99 | updateSmilXML: function( smilXML ){ |
100 | | - mw.log("Sequencer::updateSmilXML"); |
| 100 | + mw.log("Sequencer::updateSmilXML" + smilXML); |
101 | 101 | var _this = this; |
102 | | - |
| 102 | + alert( 'before update seq len: ' + this.getSmil().$dom.find('seq').children().length ) |
103 | 103 | // Update the embedPlayer smil: |
104 | 104 | this.getSmil().updateFromString( smilXML ); |
105 | | - |
| 105 | + alert( 'after update seq len: ' + this.getSmil().$dom.find('seq').children().length ) |
106 | 106 | // Get a duration ( forceRefresh to clear the cache ) |
107 | | - this.getEmbedPlayer().getDuration( true ); |
108 | | - |
| 107 | + var dur = this.getEmbedPlayer().getDuration( true ); |
| 108 | + alert( 'restored dur should be: ' + dur); |
| 109 | + /* |
109 | 110 | // redraw the timeline |
110 | 111 | this.getTimeline().drawTimeline(); |
| 112 | + */ |
111 | 113 | }, |
112 | 114 | |
113 | 115 | /** |
— | — | @@ -133,8 +135,8 @@ |
134 | 136 | // Add the timeline |
135 | 137 | _this.getTimeline().drawTimeline(); |
136 | 138 | |
137 | | - // initialize the edit actions ( stores the initial state for undo / redo actions ) |
138 | | - _this.getActionsEdit(); |
| 139 | + // initialize the edit stack to support undo / redo actions |
| 140 | + _this.getActionsEdit().setupEditStack(); |
139 | 141 | }); |
140 | 142 | // Draw the top level menu |
141 | 143 | this.getMenu().drawMenu(); |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerTimeline.js |
— | — | @@ -59,7 +59,8 @@ |
60 | 60 | this.trackLayout.resizeAll(); |
61 | 61 | } |
62 | 62 | }, |
63 | | - //draw the timeline |
| 63 | + |
| 64 | + // Draw the timeline |
64 | 65 | drawTimeline: function(){ |
65 | 66 | // Empty the timeline container |
66 | 67 | this.getTimelineContainer().empty(); |
— | — | @@ -67,7 +68,7 @@ |
68 | 69 | // Get the top level sequence tracks |
69 | 70 | var seqTracks = this.sequencer.getSmil().getBody().getSeqElements(); |
70 | 71 | var trackType = 'video'; |
71 | | - // for now just two tracks first is video second is audio |
| 72 | + // For now just two tracks first is video second is audio |
72 | 73 | for( var trackIndex=0; trackIndex < seqTracks.length; trackIndex++){ |
73 | 74 | |
74 | 75 | if( trackType == 'audio' ){ |
— | — | @@ -83,8 +84,8 @@ |
84 | 85 | drawSequenceTrack: function( trackIndex, sequenceNode, trackType ){ |
85 | 86 | var _this = this; |
86 | 87 | mw.log(" drawSequenceTrack: Track inx: " + trackIndex + ' trackType:' + trackType ); |
87 | | - // Check if we already have a container for this track set |
88 | | - |
| 88 | + // Check if we already have a container for this track set |
| 89 | + |
89 | 90 | // Add a sequence track Name |
90 | 91 | this.getTracksContainer().find('.trackNamesContainer').append( |
91 | 92 | this.getTrackNameInterface( trackIndex, sequenceNode, trackType ) |
— | — | @@ -93,12 +94,12 @@ |
94 | 95 | // Add Sequence clips |
95 | 96 | this.getTracksContainer().find('.clipTrackSetContainer').append( |
96 | 97 | this.getTrackClipInterface( trackIndex ,sequenceNode , trackType ) |
97 | | - ).click(function(){ |
| 98 | + ).click( function(){ |
98 | 99 | // xxx todo catch de-select clicks in clipTrackSetContainer that are not a click in the timeline |
99 | 100 | //_this.getTracksContainer().find('.timelineClip').removeClass( 'selectedClip' ); |
100 | 101 | }) |
101 | 102 | // Load and display all clip thumbnails |
102 | | - this.drawTrackThumbs( trackIndex, sequenceNode, trackType ); |
| 103 | + this.drawTrackThumbs( trackIndex, sequenceNode, trackType ); |
103 | 104 | }, |
104 | 105 | |
105 | 106 | drawTrackThumbs: function( trackIndex, sequenceNode, trackType ){ |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerActionsEdit.js |
— | — | @@ -23,9 +23,7 @@ |
24 | 24 | numberOfUndos : mw.getConfig( 'Sequencer.numberOfUndos' ), |
25 | 25 | |
26 | 26 | init: function( sequencer ) { |
27 | | - this.sequencer = sequencer; |
28 | | - // Set the initial edit state: |
29 | | - this.editStack.push( this.sequencer.getSmil().getXMLString() ); |
| 27 | + this.sequencer = sequencer; |
30 | 28 | }, |
31 | 29 | |
32 | 30 | selectAll: function(){ |
— | — | @@ -35,6 +33,15 @@ |
36 | 34 | }, |
37 | 35 | |
38 | 36 | /** |
| 37 | + * Set up the edit stack |
| 38 | + */ |
| 39 | + setupEditStack: function(){ |
| 40 | + this.editStack = []; |
| 41 | + // Set the initial edit state: |
| 42 | + this.editStack.push( this.sequencer.getSmil().getXMLString() ); |
| 43 | + }, |
| 44 | + |
| 45 | + /** |
39 | 46 | * Apply a smil xml transform state ( to support undo / redo ) |
40 | 47 | */ |
41 | 48 | registerEdit: function(){ |
— | — | @@ -55,9 +62,10 @@ |
56 | 63 | * Undo an edit action |
57 | 64 | */ |
58 | 65 | undo: function(){ |
59 | | - this.editIndex--; |
| 66 | + this.editIndex--; |
| 67 | + mw.log("SequenceActionsEdit:: undo stack index:" + this.editIndex); |
60 | 68 | // Change to previous state |
61 | | - this.sequencer.updateSmilXML( this.editStack[ this.editIndex ] ); |
| 69 | + this.sequencer.updateSmilXML( this.editStack[ this.editIndex ] ); |
62 | 70 | }, |
63 | 71 | |
64 | 72 | /** |