Index: branches/MwEmbedStandAlone/mwEmbed.js |
— | — | @@ -47,7 +47,9 @@ |
48 | 48 | mw.validSkins = [ 'mvpcf', 'kskin' ]; |
49 | 49 | |
50 | 50 | // Storage variable for loaded style sheet keys |
51 | | - mw.style = { }; |
| 51 | + if( ! mw.style ){ |
| 52 | + mw.style = { }; |
| 53 | + } |
52 | 54 | |
53 | 55 | /** |
54 | 56 | * Configuration System: |
Index: branches/MwEmbedStandAlone/modules/Playlist/mw.PlaylistHandlerMediaRss.js |
— | — | @@ -7,6 +7,9 @@ |
8 | 8 | // Set the media rss namespace |
9 | 9 | mediaNS: 'http://search.yahoo.com/mrss/', |
10 | 10 | |
| 11 | + // If playback should continue to the next clip on clip complete |
| 12 | + autoContinue: true, |
| 13 | + |
11 | 14 | init: function ( Playlist ){ |
12 | 15 | this.playlist = Playlist; |
13 | 16 | }, |
— | — | @@ -21,13 +24,24 @@ |
22 | 25 | callback( this.$rss ); |
23 | 26 | return ; |
24 | 27 | } |
| 28 | + |
| 29 | + // Show an error if a cross domain request: |
| 30 | + if( ! mw.isLocalDomain( this.getSrc() ) ) { |
| 31 | + mw.log("Error: trying to get cross domain playlist source: " + this.getSrc() ); |
| 32 | + } |
| 33 | + |
25 | 34 | // Note this only works with local sources |
26 | | - $j.get( mw.absoluteUrl( this.playlist.src ), function( data ){ |
| 35 | + $j.get( mw.absoluteUrl( this.getSrc() ), function( data ){ |
27 | 36 | _this.$rss = $j( data ); |
28 | 37 | callback( _this.$rss ); |
29 | 38 | }); |
30 | 39 | }, |
31 | | - |
| 40 | + hasMultiplePlaylists: function(){ |
| 41 | + return false; |
| 42 | + }, |
| 43 | + getSrc: function(){ |
| 44 | + return this.playlist.src; |
| 45 | + }, |
32 | 46 | // Get clip count |
33 | 47 | getClipCount: function(){ |
34 | 48 | if( !this.$rss ){ |
— | — | @@ -71,7 +85,7 @@ |
72 | 86 | getClipPoster: function ( clipIndex ){ |
73 | 87 | var $item = this.$rss.find('item').eq( clipIndex ); |
74 | 88 | var mediaThumb = $item.get(0).getElementsByTagNameNS( this.mediaNS, 'thumbnail' ); |
75 | | - mw.log( 'MEDIAthumb: ' + $j( mediaThumb ).attr('url' ) ); |
| 89 | + mw.log( 'mw.PlaylistMediaRss::getClipPoster: ' + $j( mediaThumb ).attr('url' ) ); |
76 | 90 | if( mediaThumb && $j( mediaThumb ).attr('url' ) ){ |
77 | 91 | return $j( mediaThumb ).attr('url' ); |
78 | 92 | } |
Index: branches/MwEmbedStandAlone/modules/Playlist/mw.Playlist.js |
— | — | @@ -77,10 +77,10 @@ |
78 | 78 | // Set the target to loadingSpinner: |
79 | 79 | $j( this.target ).empty().loadingSpinner(); |
80 | 80 | |
81 | | - this.loadPlaylistHandler( function( playlistHandler ){ |
82 | | - mw.log("mw.Playlist::loaded playlist handler"); |
| 81 | + this.loadPlaylistHandler( function( sourceHandler ){ |
| 82 | + mw.log("mw.Playlist::loaded playlist set"); |
83 | 83 | // Check if load failed or empty playlist |
84 | | - if( _this.sourceHandler.getClipList().length == 0 ){ |
| 84 | + if( sourceHandler.getClipList().length == 0 ){ |
85 | 85 | $j( _this.target ).empty().text( gM('mwe-playlist-empty') ) |
86 | 86 | return ; |
87 | 87 | } |
— | — | @@ -88,56 +88,247 @@ |
89 | 89 | // Empty the target and setup player and playerList divs |
90 | 90 | $j( _this.target ) |
91 | 91 | .empty() |
| 92 | + .css('position', 'relative' ) |
92 | 93 | .append( |
93 | 94 | $j( '<span />' ) |
94 | 95 | .addClass( 'media-rss-video-player') |
95 | 96 | .css({ |
96 | 97 | 'float' : 'left' |
97 | 98 | }) |
98 | | - , |
99 | | - $j( '<div />') |
100 | | - .addClass( 'media-rss-video-list-wrapper' ) |
| 99 | + , |
| 100 | + $j( '<div />') |
| 101 | + .addClass( 'media-rss-video-list' ) |
| 102 | + .attr('id', _this.id + '_videolist') |
| 103 | + .css({ |
| 104 | + 'position' : 'absolute', |
| 105 | + 'z-index' : '1', |
| 106 | + 'overflow' : 'auto', |
| 107 | + 'bottom': '0px', |
| 108 | + 'right' : '0px' |
| 109 | + }) |
| 110 | + .hide() |
| 111 | + ); |
| 112 | + |
| 113 | + // Check if we have multiple playlist and setup the list and bindings |
| 114 | + if( _this.sourceHandler.hasMultiplePlaylists() ){ |
| 115 | + var playlistSet = _this.sourceHandler.getPlaylistSet(); |
| 116 | + |
| 117 | + var $plListContainer =$j('<div />') |
| 118 | + .addClass( 'playlistSet-container ui-state-default ui-widget-header ui-corner-all' ) |
| 119 | + .css({ |
| 120 | + 'position' : 'absolute', |
| 121 | + 'overflow' : 'hidden', |
| 122 | + 'top' : '3px', |
| 123 | + 'right' : '0px', |
| 124 | + 'height' : '20px' |
| 125 | + }) |
| 126 | + .append( |
| 127 | + $j('<div />') |
| 128 | + .addClass( 'playlistSet-list' ) |
| 129 | + .css("width", '2000px') |
| 130 | + ); |
| 131 | + $j( _this.target ).append( $plListContainer ); |
| 132 | + |
| 133 | + var $plListSet = $j( _this.target ).find( '.playlistSet-list' ); |
| 134 | + |
| 135 | + $j.each( playlistSet, function( inx, playlist){ |
| 136 | + // add a divider |
| 137 | + if( inx != 0 ){ |
| 138 | + $plListSet.append( $j('<span />').text( ' | ') ) |
| 139 | + } |
| 140 | + $plListSet.append( |
| 141 | + $j('<a />') |
| 142 | + .attr('href', '#') |
| 143 | + .text( playlist.name ) |
| 144 | + .click( function(){ |
| 145 | + _this.sourceHandler.setPlaylistIndex( inx ); |
| 146 | + $j( _this.target + ' .media-rss-video-list').loadingSpinner(); |
| 147 | + _this.loadPlaylist( function(){ |
| 148 | + $j( _this.target + ' .media-rss-video-list').empty(); |
| 149 | + _this.addMediaList(); |
| 150 | + }); |
| 151 | + return false; |
| 152 | + }) |
| 153 | + .buttonHover() |
| 154 | + ) |
| 155 | + }); |
| 156 | + // Check playlistSet width and add scroll left / scroll right buttons |
| 157 | + if( $plListSet.width() > $plListContainer.width() ){ |
| 158 | + var baseButtonWidth = 24; |
| 159 | + $plListSet.css( { |
| 160 | + 'position': 'absolute', |
| 161 | + 'left' : baseButtonWidth + 'px' |
| 162 | + }); |
| 163 | + var $scrollButton = $j('<div />') |
| 164 | + .addClass( 'ui-corner-all ui-state-default' ) |
101 | 165 | .css({ |
102 | | - 'position' : 'relative', |
103 | | - 'z-index' : '1', |
104 | | - 'width': '400px', |
105 | | - 'height': '300px', |
106 | | - 'overflow' : 'auto' |
| 166 | + 'position' : 'absolute', |
| 167 | + 'top' : '-1px', |
| 168 | + 'cursor' : 'pointer', |
| 169 | + 'margin' :'0px', |
| 170 | + 'padding' : '2px', |
| 171 | + 'width' : '16px', |
| 172 | + 'height' : '16px' |
107 | 173 | }) |
| 174 | + |
| 175 | + var $buttonSpan = $j('<span />') |
| 176 | + .addClass( 'ui-icon' ) |
| 177 | + .css('margin', '2px' ); |
| 178 | + |
| 179 | + var plScrollPos = 0; |
| 180 | + var scrollToListPos = function( pos ){ |
| 181 | + |
| 182 | + listSetLeft = $plListSet.find('a').eq( pos ).offset().left - |
| 183 | + $plListSet.offset().left ; |
| 184 | + |
| 185 | + mw.log("scroll to: " + pos + ' left: ' + listSetLeft); |
| 186 | + $plListSet.animate({'left': -( listSetLeft - baseButtonWidth) + 'px'} ); |
| 187 | + } |
| 188 | + |
| 189 | + $plListContainer |
108 | 190 | .append( |
109 | | - $j( '<div />') |
110 | | - .addClass( 'media-rss-video-list' ) |
111 | | - .attr('id', _this.id + '_videolist') |
| 191 | + $scrollButton.clone() |
| 192 | + .css('left', '0px') |
| 193 | + .append( $buttonSpan.clone().addClass('ui-icon-circle-arrow-w') ) |
| 194 | + .click( function(){ |
| 195 | + //slide right |
| 196 | + if( plScrollPos >= 0){ |
| 197 | + mw.log("scroll right"); |
| 198 | + plScrollPos-- |
| 199 | + scrollToListPos( plScrollPos ); |
| 200 | + } |
| 201 | + }) |
| 202 | + .buttonHover(), |
| 203 | + |
| 204 | + $scrollButton.clone() |
| 205 | + .css('right', '0px') |
| 206 | + .append( $buttonSpan.clone().addClass('ui-icon-circle-arrow-e') ) |
| 207 | + .click( function(){ |
| 208 | + //slide left |
| 209 | + if( plScrollPos < $plListSet.find('a').length-1 ){ |
| 210 | + plScrollPos++; |
| 211 | + scrollToListPos( plScrollPos ); |
| 212 | + } |
| 213 | + }) |
| 214 | + .buttonHover() |
112 | 215 | ) |
113 | | - .hide() |
114 | | - ); |
| 216 | + } |
| 217 | + } |
115 | 218 | |
116 | 219 | // Add the selectable media list |
117 | 220 | _this.addMediaList(); |
118 | 221 | |
119 | 222 | // Add the player |
120 | | - _this.updatePlayer( _this.clipIndex, function(){ |
121 | | - |
| 223 | + _this.updatePlayer( _this.clipIndex, function(){ |
122 | 224 | // Update the list height ( vertical layout ) |
123 | | - if( _this.layout == 'vertical' ){ |
124 | | - var targetListHeight = ( $j( _this.target ).height() - $j( _this.target + ' .media-rss-video-player' ).height() ); |
125 | | - $j( _this.target + ' .media-rss-video-list-wrapper' ).css( { |
126 | | - 'height' : targetListHeight, |
| 225 | + if( _this.layout == 'vertical' ){ |
| 226 | + $j( _this.target + ' .media-rss-video-list' ).css( { |
| 227 | + 'top' : $j( _this.target + ' .media-rss-video-player' ).height() + 4, |
127 | 228 | 'width' : '100%' |
128 | 229 | } ) |
| 230 | + // Add space for the multi-playlist selector: |
| 231 | + if( _this.sourceHandler.hasMultiplePlaylists() ){ |
| 232 | + // also adjust .playlistSet-container if present |
| 233 | + $j( _this.target + ' .playlistSet-container').css( { |
| 234 | + 'top' : $j( _this.target + ' .media-rss-video-player' ).height() + 4 |
| 235 | + }) |
| 236 | + $j( _this.target + ' .media-rss-video-list' ).css({ |
| 237 | + 'top' : $j( _this.target + ' .media-rss-video-player' ).height() + 26 |
| 238 | + }) |
| 239 | + } |
| 240 | + |
129 | 241 | } else { |
130 | | - var targetListWidth = ( $j( _this.target ).width() - $j( _this.target + ' .media-rss-video-player' ).width() ); |
131 | | - $j( _this.target + ' .media-rss-video-list-wrapper').css( { |
132 | | - 'width' : targetListWidth, |
133 | | - 'height' : '100%' |
134 | | - } ) |
| 242 | + // Update horizontal layout |
| 243 | + $j( _this.target + ' .media-rss-video-list').css( { |
| 244 | + 'top' : '0px', |
| 245 | + 'left' : $j( _this.target + ' .media-rss-video-player' ).width() + 4 |
| 246 | + } ) |
| 247 | + // Add space for the multi-playlist selector: |
| 248 | + if( _this.sourceHandler.hasMultiplePlaylists() ){ |
| 249 | + $j( _this.target + ' .playlistSet-container').css( { |
| 250 | + 'left' : $j( _this.target + ' .media-rss-video-player' ).width() + 4 |
| 251 | + }) |
| 252 | + $j( _this.target + ' .media-rss-video-list').css( { |
| 253 | + 'top' : '26px' |
| 254 | + }) |
| 255 | + } |
135 | 256 | } |
| 257 | + var $videoList = $j( _this.target + ' .media-rss-video-list' ); |
| 258 | + $videoList.show() |
136 | 259 | // show the video list and apply the swipe binding |
137 | 260 | $j( _this.target ).find('.media-rss-video-list-wrapper').fadeIn(); |
138 | 261 | if( mw.isMobileSafari() ){ |
| 262 | + // iScroll is buggy with current version of iPad / iPhone use scroll buttons instead |
| 263 | + /* |
139 | 264 | document.addEventListener('touchmove', function(e){ e.preventDefault(); }); |
140 | 265 | var myScroll = iScroll( _this.id + '_videolist' ); |
141 | 266 | setTimeout(function () { myScroll.refresh(); }, 0); |
| 267 | + */ |
| 268 | + // add space for scroll buttons: |
| 269 | + var curTop = $j( _this.target + ' .media-rss-video-list' ).css('top'); |
| 270 | + if(!curTop) curTop = '0px'; |
| 271 | + $j( _this.target + ' .media-rss-video-list' ).css( { |
| 272 | + 'position' : 'absolute', |
| 273 | + 'height' : null, |
| 274 | + 'top' : curTop, |
| 275 | + 'bottom' : '30px', |
| 276 | + 'right': '0px' |
| 277 | + }) |
| 278 | + if( _this.layout == 'vertical' ){ |
| 279 | + $j( _this.target + ' .media-rss-video-list' ).css({ |
| 280 | + 'top' : $j( _this.target + ' .media-rss-video-player' ).height() |
| 281 | + }) |
| 282 | + } |
| 283 | + // Add scroll buttons: |
| 284 | + $j( _this.target ).append( |
| 285 | + $j( '<div />').css({ |
| 286 | + 'position' : 'absolute', |
| 287 | + 'bottom' : '0px', |
| 288 | + 'right': '0px', |
| 289 | + 'height' : '30px', |
| 290 | + 'width' : $j( _this.target + ' .media-rss-video-list').width() |
| 291 | + }) |
| 292 | + .append( |
| 293 | + $j.button({ |
| 294 | + 'text' : 'scroll down', |
| 295 | + 'icon_id' : 'circle-arrow-s' |
| 296 | + }) |
| 297 | + .css('float', 'right') |
| 298 | + .click(function(){ |
| 299 | + var clipListCount = $videoList.children().length; |
| 300 | + var clipSize = $videoList.children(':first').height(); |
| 301 | + var curTop = $videoList.attr('scrollTop'); |
| 302 | + |
| 303 | + var targetPos = curTop + (clipSize * 3); |
| 304 | + if( targetPos > clipListCount * clipSize ){ |
| 305 | + targetPos = ( clipListCount * ( clipSize -1 ) ); |
| 306 | + } |
| 307 | + //mw.log(" animate to: " +curTop + ' + ' + (clipSize * 3) + ' = ' + targetPos ); |
| 308 | + $videoList.animate({'scrollTop': targetPos }, 500 ); |
| 309 | + |
| 310 | + return false; |
| 311 | + }), |
| 312 | + $j.button({ |
| 313 | + 'text' : 'scroll up', |
| 314 | + 'icon_id' : 'circle-arrow-n' |
| 315 | + }) |
| 316 | + .css('float', 'left') |
| 317 | + .click(function(){ |
| 318 | + var clipListCount = $videoList.children().length; |
| 319 | + var clipSize = $videoList.children(':first').height(); |
| 320 | + var curTop = $videoList.attr('scrollTop'); |
| 321 | + |
| 322 | + var targetPos = curTop - (clipSize * 3); |
| 323 | + if( targetPos < 0 ){ |
| 324 | + targetPos = 0 |
| 325 | + } |
| 326 | + mw.log(" animate to: " +curTop + ' + ' + (clipSize * 3) + ' = ' + targetPos ); |
| 327 | + $videoList.animate({'scrollTop': targetPos }, 500 ); |
| 328 | + |
| 329 | + return false; |
| 330 | + }) |
| 331 | + ) |
| 332 | + ) |
142 | 333 | } |
143 | 334 | |
144 | 335 | }); |
— | — | @@ -191,16 +382,15 @@ |
192 | 383 | |
193 | 384 | // Build and output the title |
194 | 385 | var $title = $j('<div />' ) |
195 | | - .addClass( 'playlist-title') |
| 386 | + .addClass( 'playlist-title ui-state-default ui-widget-header ui-corner-all') |
196 | 387 | .css( { |
| 388 | + 'top' : '0px', |
197 | 389 | 'height' : _this.titleHeight, |
198 | | - 'font-size' : '85%', |
199 | 390 | 'width' : playerSize.width |
200 | 391 | } ) |
201 | 392 | .text( |
202 | 393 | _this.sourceHandler.getClipTitle( clipIndex ) |
203 | 394 | ) |
204 | | - .addClass( 'ui-state-default ui-widget-header' ) |
205 | 395 | |
206 | 396 | $j( _this.target + ' .media-rss-video-player' ).find('.playlist-title').remove( ); |
207 | 397 | $j( _this.target + ' .media-rss-video-player' ).prepend( $title ); |
— | — | @@ -281,25 +471,27 @@ |
282 | 472 | |
283 | 473 | // Update the video tag with the embedPlayer |
284 | 474 | $j.embedPlayers( function(){ |
285 | | - // Setup ondone playing binding to play next clip |
286 | | - $j( '#mrss_' + _this.id + '_' + _this.clipIndex ).unbind('ended').bind( 'ended', function(event, onDoneActionObject ){ |
287 | | - // Play next clip |
288 | | - if( _this.clipIndex + 1 < _this.sourceHandler.getClipCount() ){ |
289 | | - // Update the onDone action object to not run the base control done: |
290 | | - onDoneActionObject.runBaseControlDone = false; |
291 | | - _this.clipIndex++; |
292 | | - |
293 | | - // update the player and play the next clip |
294 | | - _this.updatePlayer( _this.clipIndex, function(){ |
295 | | - _this.play(); |
296 | | - }) |
297 | | - |
298 | | - } else { |
299 | | - mw.log("Reached end of playlist run normal end action" ); |
300 | | - // Update the onDone action object to not run the base control done: |
301 | | - onDoneActionObject.runBaseControlDone = true; |
302 | | - } |
303 | | - }) |
| 475 | + // Setup ondone playing binding to play next clip (if autoContinue is true ) |
| 476 | + if( _this.sourceHandler.autoContinue == true ){ |
| 477 | + $j( '#mrss_' + _this.id + '_' + _this.clipIndex ).unbind('ended').bind( 'ended', function(event, onDoneActionObject ){ |
| 478 | + // Play next clip |
| 479 | + if( _this.clipIndex + 1 < _this.sourceHandler.getClipCount() ){ |
| 480 | + // Update the onDone action object to not run the base control done: |
| 481 | + onDoneActionObject.runBaseControlDone = false; |
| 482 | + _this.clipIndex++; |
| 483 | + |
| 484 | + // update the player and play the next clip |
| 485 | + _this.updatePlayer( _this.clipIndex, function(){ |
| 486 | + _this.play(); |
| 487 | + }) |
| 488 | + |
| 489 | + } else { |
| 490 | + mw.log("Reached end of playlist run normal end action" ); |
| 491 | + // Update the onDone action object to not run the base control done: |
| 492 | + onDoneActionObject.runBaseControlDone = true; |
| 493 | + } |
| 494 | + }) |
| 495 | + } |
304 | 496 | // Run the callback if its set |
305 | 497 | if( callback ){ |
306 | 498 | callback(); |
— | — | @@ -345,7 +537,7 @@ |
346 | 538 | 'alt' : _this.sourceHandler.getClipTitle( inx ), |
347 | 539 | 'src' : _this.sourceHandler.getClipPoster( inx ) |
348 | 540 | }) |
349 | | - .css( 'width', _this.itemThumbWidth ) |
| 541 | + .css( 'width', _this.itemThumbWidth + 'px') |
350 | 542 | ), |
351 | 543 | $j( '<td />') |
352 | 544 | .text( _this.sourceHandler.getClipTitle( inx ) ), |
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBuffer.js |
— | — | @@ -162,7 +162,9 @@ |
163 | 163 | switch( this.smil.getRefType( smilElement ) ){ |
164 | 164 | case 'video': |
165 | 165 | var vid = $j( '#' + this.smil.getPageDomId( smilElement ) ).get(0); |
166 | | - |
| 166 | + if( !vid ){ |
| 167 | + break; |
| 168 | + } |
167 | 169 | // The load request does not work very well instead .play() then .pause() and seek when on display |
168 | 170 | // vid.load(); |
169 | 171 | |
— | — | @@ -170,10 +172,8 @@ |
171 | 173 | if( vid.paused && this.getVideoPercetLoaded( smilElement ) == 0 ){ |
172 | 174 | // Issue the load / play request |
173 | 175 | vid.play(); |
174 | | - vid.volume = 0; |
175 | | - |
176 | | - // XXX seek to clipBegin if provided ( we don't need to load before that point ) |
177 | | - |
| 176 | + vid.volume = 0; |
| 177 | + // XXX seek to clipBegin if provided ( we don't need to load before that point ) |
178 | 178 | } else { |
179 | 179 | //mw.log("loadElement:: pause video: " + this.smil.getPageDomId( smilElement )); |
180 | 180 | // else we have some percentage loaded pause playback |
Index: branches/MwEmbedStandAlone/modules/Sequencer/Sequencer.i18n.php |
— | — | @@ -9,6 +9,9 @@ |
10 | 10 | $messages = array(); |
11 | 11 | $messages['en'] = array( |
12 | 12 | 'mwe-sequencer-loading-sequencer' => 'Loading sequencer ...', |
| 13 | + |
| 14 | + 'mwe-sequencer-visual-editor'=> "Visual sequence editor", |
| 15 | + 'mwe-sequencer-text-editor-warn'=> 'Text XML editor ( not recommended ) ', |
13 | 16 | 'mwe-sequencer-loading-timeline' => 'Loading timeline ...', |
14 | 17 | 'mwe-sequencer-loading-player' => 'Loading player ...', |
15 | 18 | 'mwe-sequencer-loading-menu' => 'Loading menu ...', |
— | — | @@ -76,12 +79,14 @@ |
77 | 80 | |
78 | 81 | 'mwe-sequencer-save-no-changes' => 'There are no new edits to save', |
79 | 82 | 'mwe-sequencer-save-summary' => 'Please enter a short summary of changes:', |
80 | | - 'mwe-sequencer-edit_cancel' => 'Cancel sequence edit', |
81 | | - |
| 83 | + 'mwe-sequencer-edit_cancel' => 'Cancel sequence edit', |
82 | 84 | 'mwe-sequencer-saving_wait' => 'Save in progress (please wait)', |
83 | 85 | 'mwe-sequencer-save_done' => 'Save complete', |
84 | 86 | |
| 87 | + 'mwe-sequencer-open-summary' => "Enter the name of the sequence you would like to open", |
| 88 | + |
85 | 89 | |
| 90 | + |
86 | 91 | 'mwe-sequencer-not-published' => 'This sequence has not yet been published. <i>Browser preview is shown</i>. <b>[$1 Review and publish this sequence]</b>.', |
87 | 92 | 'mwe-sequencer-published-out-of-date' =>'This published sequence is not the most recent version. You can <b>[$1 review and publish]</b> the most recent version.', |
88 | 93 | |
Index: branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsSequence.js |
— | — | @@ -15,6 +15,72 @@ |
16 | 16 | init: function( sequencer ) { |
17 | 17 | this.sequencer = sequencer; |
18 | 18 | }, |
| 19 | + |
| 20 | + /** |
| 21 | + * present an open dialog to the user, and open the sequence in a new window |
| 22 | + */ |
| 23 | + open: function(){ |
| 24 | + var _this = this; |
| 25 | + var $content = $j('<div />').append( |
| 26 | + gM('mwe-sequencer-open-summary' ), |
| 27 | + $j('<input />') |
| 28 | + .css({ 'width': 400 }) |
| 29 | + .attr({ |
| 30 | + 'id' : 'sequenceOpenNameInput', |
| 31 | + 'maxlength': 255 |
| 32 | + }) |
| 33 | + // Make sure keys press does not affect the sequencer interface |
| 34 | + .sequencerInput( _this.sequencer ) |
| 35 | + ); |
| 36 | + // XXX todo we should have an autocomplete on sequence name! |
| 37 | + |
| 38 | + var buttons = {}; |
| 39 | + buttons[ gM('mwe-cancel') ] = function(){ $j( this ).dialog( 'cancel' ) }; |
| 40 | + |
| 41 | + // For now just support server based open .. ideally we could browse for file |
| 42 | + var $dialog = mw.addDialog({ |
| 43 | + 'resizable':'true', |
| 44 | + 'title' : gM('mwe-sequencer-menu-sequence-open-desc'), |
| 45 | + 'content' : $content, |
| 46 | + 'buttons' : buttons, |
| 47 | + 'width' : 450 |
| 48 | + }); |
| 49 | + // Add a special open button |
| 50 | + $dialog.parent().find( '.ui-dialog-buttonpane' ).prepend( |
| 51 | + $j.button({ |
| 52 | + 'icon' : 'folder-open', |
| 53 | + 'text' : gM('mwe-sequencer-menu-sequence-open') |
| 54 | + }) |
| 55 | + // Match button layout |
| 56 | + .css({ |
| 57 | + 'margin':'0.5em 0.4em 0.5em 0', |
| 58 | + 'padding' : '0.2em 1.4em 0.3em' |
| 59 | + }) |
| 60 | + .attr({ |
| 61 | + 'id' : 'sequenceOpenButton', |
| 62 | + 'target' : '_new', |
| 63 | + 'href' : '#' |
| 64 | + }).click( function(){ |
| 65 | + // Update the link |
| 66 | + $j(this).attr({ |
| 67 | + 'href': |
| 68 | + mw.getRemoteSequencerLink( |
| 69 | + mw.escapeQuotesHTML( |
| 70 | + _this.sequencer.getServer().getSequenceViewUrl( |
| 71 | + // ( Sequence: is automatically pre-appended with getSequencePageUrl |
| 72 | + // ( don't use Sequence: in the title ) |
| 73 | + $j('#sequenceOpenNameInput').val().replace(/Sequence:/i, '') |
| 74 | + ) |
| 75 | + ) |
| 76 | + ) |
| 77 | + }); |
| 78 | + // Close the dialog |
| 79 | + $j(this).dialog( 'close' ); |
| 80 | + // Follow the link |
| 81 | + return true; |
| 82 | + }) |
| 83 | + ) |
| 84 | + }, |
19 | 85 | save: function(){ |
20 | 86 | var _this = this; |
21 | 87 | var $dialog = mw.addDialog({ |
— | — | @@ -66,7 +132,6 @@ |
67 | 133 | ); |
68 | 134 | // Remove buttons while loading |
69 | 135 | $dialog.dialog( "option", "buttons", {} ); |
70 | | - $dialog.dialog( "option", "title", gM('mwe-sequencer-saving_wait' ) ); |
71 | 136 | |
72 | 137 | _this.sequencer.getServer().save( |
73 | 138 | /* Save summary */ |
— | — | @@ -194,8 +259,7 @@ |
195 | 260 | .text("%"), |
196 | 261 | $j('<div />').attr( 'id', 'firefoggProgressbar') |
197 | 262 | |
198 | | - ); |
199 | | - $j('<div />').attr( 'id', 'firefoggProgressbar') |
| 263 | + ); |
200 | 264 | // Embed the player and continue application flow |
201 | 265 | $j('#publishVideoTarget').embedPlayer({ |
202 | 266 | 'controls' : false |
— | — | @@ -212,9 +276,10 @@ |
213 | 277 | progressPrecent + |
214 | 278 | '%' |
215 | 279 | ) |
216 | | - $j("#firefoggProgressbar").progressbar( |
217 | | - "option", "value", Math.round( progress * 100 ) |
218 | | - ); |
| 280 | + mw.log( "set progrees to: " + Math.round( progress * 100 ) ); |
| 281 | + $j("#firefoggProgressbar").progressbar({ |
| 282 | + "value" : Math.round( progress * 100 ) |
| 283 | + }); |
219 | 284 | }, |
220 | 285 | 'doneRenderCallback': function( fogg ){ |
221 | 286 | _this.uploadRenderedVideo( $dialog, fogg ); |
— | — | @@ -281,7 +346,7 @@ |
282 | 347 | uploadDone: function($dialog, apiResult){ |
283 | 348 | var _this = this; |
284 | 349 | // Check the api response |
285 | | - if ( apiResult.error || ( apiResult.upload && |
| 350 | + if ( !apiResult || apiResult.error || ( apiResult.upload && |
286 | 351 | ( apiResult.upload.result == "Failure" || apiResult.upload.error ) ) ) { |
287 | 352 | |
288 | 353 | $dialog.dialog( 'option', 'title', gM('mwe-sequencer-publishing-error' ) ); |
— | — | @@ -292,12 +357,20 @@ |
293 | 358 | |
294 | 359 | // Success link to the sequence page / ok closes dialog |
295 | 360 | $dialog.dialog( 'option', 'title', gM('mwe-sequencer-publishing-success' ) ); |
| 361 | + var button = {}; |
| 362 | + button[ gM('mwe-ok') ] = function(){ |
| 363 | + $j( this ).dialog('close') |
| 364 | + }; |
| 365 | + $dialog.dialog( 'option', 'button', button ); |
| 366 | + // for some reason we lose button height :( (jquery bug ? ) |
| 367 | + $dialog.parent().css( 'height', $dialog.height() + 100 ); |
| 368 | + |
296 | 369 | $dialog.empty().html( gM('mwe-sequencer-publishing-success-desc', |
297 | 370 | $j('<a />') |
298 | 371 | .attr({ |
299 | 372 | 'target': '_new', |
300 | 373 | 'href': wgArticlePath.replace( '$1', 'File:' +_this.sequencer.getServer().getVideoFileName() ) |
301 | | - }) |
| 374 | + }) |
302 | 375 | ) ); |
303 | 376 | // Update the buttons |
304 | 377 | var buttons = {}; |
Index: branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsEdit.js |
— | — | @@ -17,15 +17,15 @@ |
18 | 18 | editStack : [], |
19 | 19 | |
20 | 20 | // Store the edit index |
21 | | - editIndex : 0, |
| 21 | + editIndex : 0, |
22 | 22 | |
23 | | - // The numbers of undos supported |
24 | | - numberOfUndos : mw.getConfig( 'Sequencer.numberOfUndos' ), |
25 | | - |
26 | 23 | init: function( sequencer ) { |
27 | 24 | this.sequencer = sequencer; |
28 | 25 | }, |
29 | | - |
| 26 | + // return the configured numbers of undos supported |
| 27 | + getNumberOfUndos: function(){ |
| 28 | + return mw.getConfig( 'Sequencer.NumberOfUndos' ); |
| 29 | + }, |
30 | 30 | selectAll: function(){ |
31 | 31 | // Select all the items in the timeline |
32 | 32 | $target = this.sequencer.getTimeline().getTimelineContainer(); |
— | — | @@ -60,9 +60,15 @@ |
61 | 61 | this.editStack = this.editStack.splice(0, this.editIndex); |
62 | 62 | } |
63 | 63 | |
| 64 | + // Shift the undo index if we have hit our max undo size |
| 65 | + if( this.editStack.length > this.getNumberOfUndos() ){ |
| 66 | + this.editStack = this.editStack.splice(0, 1 ); |
| 67 | + } |
| 68 | + |
64 | 69 | // @@TODO could save space to just compute the diff in JS and store that |
65 | 70 | // ie: http://code.google.com/p/google-diff-match-patch/ |
66 | 71 | // ( instead of the full xml text with "key-pages" every 10 edits or something like that. |
| 72 | + // ( should non-block compress in workerThread / need workerThread architecture ) |
67 | 73 | this.editStack.push( currentXML ); |
68 | 74 | |
69 | 75 | // Update the editIndex |
— | — | @@ -70,6 +76,7 @@ |
71 | 77 | |
72 | 78 | // Enable the undo option: |
73 | 79 | this.sequencer.getMenu().enableMenuItem( 'edit', 'undo' ); |
| 80 | + this.sequencer.getMenu().enableMenuItem( 'sequencer', 'save' ); |
74 | 81 | }, |
75 | 82 | |
76 | 83 | /** |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerMenu.js |
— | — | @@ -36,6 +36,7 @@ |
37 | 37 | 'save_divider': 'divider', |
38 | 38 | 'save' : { |
39 | 39 | 'icon' : 'disk', |
| 40 | + 'disabled' : true, |
40 | 41 | 'shortCut' : 'ctrl S', |
41 | 42 | 'action' : function( _this ){ |
42 | 43 | mw.log("SequencerMenu::save"); |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerConfig.js |
— | — | @@ -13,9 +13,16 @@ |
14 | 14 | mw.setDefaultConfig({ |
15 | 15 | // If the sequencer should attribute kaltura |
16 | 16 | "Sequencer.KalturaAttribution" : true, |
17 | | - |
| 17 | + |
| 18 | + // If a the sequencer should open new windows |
| 19 | + "Sequencer.SpawnNewWindows" : true, |
| 20 | + |
| 21 | + // If a the sequencer should include withJS=MediaWiki:mwEmbed in created urls |
| 22 | + // ( save gards ) against users that are 'trying' the |
| 23 | + "Sequencer.WithJsMwEmbedUrlHelper" : true, |
| 24 | + |
18 | 25 | // The size of the undo stack |
19 | | - "Sequencer.numberOfUndos" : 100, |
| 26 | + "Sequencer.NumberOfUndos" : 100, |
20 | 27 | |
21 | 28 | // Default image duration |
22 | 29 | "Sequencer.AddMediaImageDuration" : 2, |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerServer.js |
— | — | @@ -26,6 +26,9 @@ |
27 | 27 | // The sequence title key for api queries |
28 | 28 | titleKey: null, |
29 | 29 | |
| 30 | + // The Url path the the sequence page with $1 where the title should be |
| 31 | + pagePathUrl: null, |
| 32 | + |
30 | 33 | // Stores the most recent version of the sequence xml from the server |
31 | 34 | serverSmilXml: null, |
32 | 35 | |
— | — | @@ -42,12 +45,20 @@ |
43 | 46 | |
44 | 47 | // NOTE this should trigger an apiHandler once we have more than one api backend |
45 | 48 | if( serverConfig ){ |
| 49 | + |
46 | 50 | if( serverConfig.type ) |
47 | 51 | this.apiType = serverConfig.type; |
| 52 | + |
48 | 53 | if( serverConfig.url ) |
49 | 54 | this.apiUrl = serverConfig.url; |
| 55 | + |
50 | 56 | if( serverConfig.titleKey ) |
51 | 57 | this.titleKey = serverConfig.titleKey; |
| 58 | + |
| 59 | + if( serverConfig.pagePathUrl ){ |
| 60 | + this.pagePathUrl = serverConfig.pagePathUrl; |
| 61 | + } |
| 62 | + |
52 | 63 | } |
53 | 64 | if( this.isConfigured() ){ |
54 | 65 | mw.log("Error: Sequencer server needs a full serverConfig to be initialized") |
— | — | @@ -200,6 +211,32 @@ |
201 | 212 | }); |
202 | 213 | }, |
203 | 214 | /** |
| 215 | + * Get the sequence description page url |
| 216 | + * @param {String} Optional Sequence title key |
| 217 | + */ |
| 218 | + getSequenceViewUrl: function( titleKey ){ |
| 219 | + if( !titleKey ) |
| 220 | + titleKey = this.titleKey; |
| 221 | + // Check that we have a pagePathUrl config: |
| 222 | + if( !this.pagePathUrl ){ |
| 223 | + return false; |
| 224 | + } |
| 225 | + return this.pagePathUrl.replace( '$1', 'Sequence:' + titleKey); |
| 226 | + }, |
| 227 | + /** |
| 228 | + * Get the sequencer 'edit' url |
| 229 | + */ |
| 230 | + getSequenceEditUrl: function( titleKey ){ |
| 231 | + if( !titleKey ) |
| 232 | + titleKey = this.titleKey; |
| 233 | + // Check that we have a pagePathUrl config: |
| 234 | + if( !this.pagePathUrl ){ |
| 235 | + return false; |
| 236 | + } |
| 237 | + return this.pagePathUrl.replace( '$1', 'Sequence:' + titleKey); |
| 238 | + }, |
| 239 | + |
| 240 | + /** |
204 | 241 | * Get the video file name for saving the flat video asset to the server |
205 | 242 | * @return {String} |
206 | 243 | */ |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerTimeline.js |
— | — | @@ -212,14 +212,21 @@ |
213 | 213 | |
214 | 214 | // Add global TrackClipInterface bindings: |
215 | 215 | var keyBindings = this.sequencer.getKeyBindings(); |
216 | | - keyBindings.bindEvent({ |
217 | | - 'escape': function(){ |
218 | | - _this.getTimelineContainer().find( '.selectedClip' ).removeClass( 'selectedClip' ); |
219 | | - }, |
220 | | - 'delete': function(){ |
| 216 | + $j( keyBindings ).bind('escape', function(){ |
| 217 | + // If a clips are selected deselect |
| 218 | + var selectedClips = _this.getTimelineContainer().find( '.selectedClip' ) |
| 219 | + if( selectedClips.length ){ |
| 220 | + selectedClips.removeClass( 'selectedClip' ); |
| 221 | + return; |
| 222 | + } |
| 223 | + // Else trigger an exit request |
| 224 | + _this.sequencer.getActionsSequence().exit(); |
| 225 | + // stop event propagation |
| 226 | + return false; |
| 227 | + }); |
| 228 | + $j( keyBindings ).bind('delete', function(){ |
221 | 229 | _this.removeSelectedClips(); |
222 | | - } |
223 | | - }) |
| 230 | + }); |
224 | 231 | }, |
225 | 232 | |
226 | 233 | getTrackSetId:function( trackIndex ){ |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerKeyBindings.js |
— | — | @@ -25,37 +25,12 @@ |
26 | 26 | // set of key flags: |
27 | 27 | shiftDown: false, |
28 | 28 | ctrlDown: false, |
29 | | - |
| 29 | + /* events */ |
| 30 | + |
30 | 31 | init: function( sequencer ){ |
31 | 32 | this.sequencer = sequencer; |
32 | 33 | this.setupKeyBindigs() |
33 | 34 | }, |
34 | | - |
35 | | - bindEvent: function( eventType, callback){ |
36 | | - if( typeof eventType == 'object' ){ |
37 | | - for( var i in eventType ){ |
38 | | - this.bindEvent( i, eventType[i] ); |
39 | | - } |
40 | | - } |
41 | | - switch( eventType ){ |
42 | | - case 'copy': |
43 | | - this.copyEvent = callback; |
44 | | - break; |
45 | | - case 'cut': |
46 | | - this.cutEvent = callback; |
47 | | - break; |
48 | | - case 'paste' : |
49 | | - this.pasteEvent = callback; |
50 | | - break; |
51 | | - case 'escape' : |
52 | | - this.escapeEvent = callback; |
53 | | - break; |
54 | | - case 'delete': |
55 | | - this.deleteEvent = callback; |
56 | | - break; |
57 | | - } |
58 | | - return this; |
59 | | - }, |
60 | 35 | onFocus: function( ){ |
61 | 36 | this.inputFocus = true; |
62 | 37 | }, |
— | — | @@ -74,14 +49,14 @@ |
75 | 50 | _this.ctrlDown = true; |
76 | 51 | |
77 | 52 | if ( ( e.which == 67 && _this.ctrlDown ) && !_this.inputFocus ) |
78 | | - _this.copyEvent(); |
| 53 | + $j( _this ).trigger( 'copy '); |
79 | 54 | |
80 | 55 | if ( ( e.which == 88 && _this.ctrlDown ) && !_this.inputFocus ) |
81 | | - _this.cutEvent(); |
| 56 | + $j( _this ).trigger( 'cut '); |
82 | 57 | |
83 | 58 | // Paste cips on v + ctrl while not focused on a text area: |
84 | 59 | if ( ( e.which == 86 && _this.ctrlDown ) && !_this.inputFocus ) |
85 | | - _this.pasteEvent(); |
| 60 | + $j( _this ).trigger( 'paste '); |
86 | 61 | |
87 | 62 | } ); |
88 | 63 | $j( window ).keyup( function( e ) { |
— | — | @@ -95,12 +70,12 @@ |
96 | 71 | |
97 | 72 | // Escape key ( deselect ) |
98 | 73 | if ( e.which == 27 ) |
99 | | - _this.escapeEvent(); |
| 74 | + $j( _this ).trigger( 'escape' ); |
100 | 75 | |
101 | 76 | |
102 | 77 | // Backspace or Delete key while not focused on a text area: |
103 | 78 | if ( ( e.which == 8 || e.which == 46 ) && !_this.inputFocus ) |
104 | | - _this.deleteEvent(); |
| 79 | + $j( _this ).trigger( 'delete' ); |
105 | 80 | } ); |
106 | 81 | } |
107 | 82 | |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerAddByUrl.js |
— | — | @@ -28,7 +28,7 @@ |
29 | 29 | * @param {Object} remoteSearchDriver The remote search driver |
30 | 30 | */ |
31 | 31 | addByUrlDialog: function( remoteSearchDriver, url ){ |
32 | | - // see if the asset matches the key type of any enabled content provider: |
| 32 | + // See if the asset matches the detailsUrl key type of any enabled content provider: |
33 | 33 | $j.each( remoteSearchDriver.getEnabledProviders(), function(providerName, provider){ |
34 | 34 | |
35 | 35 | }); |
Index: branches/MwEmbedStandAlone/modules/Sequencer/remotes/mw.MediaWikiRemoteSequencer.js |
— | — | @@ -13,10 +13,34 @@ |
14 | 14 | "mwe-sequencer-embed-sequence-desc", |
15 | 15 | "mwe-sequencer-loading-sequencer", |
16 | 16 | |
| 17 | + "mwe-sequencer-visual-editor", |
| 18 | + "mwe-sequencer-text-editor-warn", |
| 19 | + |
| 20 | + |
17 | 21 | "mwe-sequencer-not-published", |
18 | 22 | "mwe-sequencer-published-out-of-date" |
19 | 23 | ]); |
20 | 24 | |
| 25 | +/* exported functions */ |
| 26 | + |
| 27 | +/** |
| 28 | + * Special wrapper for sequence links when in 'extension' mode |
| 29 | + * there is no need for js rewrite helpers |
| 30 | + * |
| 31 | + * @param {String} url The url to be wrapped |
| 32 | + */ |
| 33 | +mw.getRemoteSequencerLink = function( url ){ |
| 34 | + if( mw.getConfig( 'Sequencer.WithJsMwEmbedUrlHelper' ) ){ |
| 35 | + if( url.indexOf('?') == -1){ |
| 36 | + url+='?' |
| 37 | + } else { |
| 38 | + url+='&' |
| 39 | + } |
| 40 | + url+='withJS=MediaWiki:MwEmbed.js'; |
| 41 | + } |
| 42 | + return url; |
| 43 | +}, |
| 44 | + |
21 | 45 | mw.MediaWikiRemoteSequencer = function( options ) { |
22 | 46 | return this.init( options ); |
23 | 47 | }; |
— | — | @@ -29,14 +53,17 @@ |
30 | 54 | this.action = ( options.action )? options.action : this.action; |
31 | 55 | this.title = ( options.title )? options.title : this.title; |
32 | 56 | this.target = ( options.target )? options.target : this.target; |
33 | | - }, |
| 57 | + }, |
34 | 58 | |
35 | 59 | drawUI: function() { |
36 | 60 | // Check page action |
37 | 61 | if( this.action == 'view' ) { |
38 | 62 | this.showViewUI(); |
39 | 63 | } |
40 | | - }, |
| 64 | + if( this.action == 'edit' ){ |
| 65 | + this.showEditUI(); |
| 66 | + } |
| 67 | + }, |
41 | 68 | /** |
42 | 69 | * Check page for sequence |
43 | 70 | * if not present give link to "create" one. |
— | — | @@ -72,9 +99,48 @@ |
73 | 100 | _this.displayPlayerEmbed(); |
74 | 101 | } |
75 | 102 | }, |
| 103 | + |
| 104 | + showEditUI: function(){ |
| 105 | + |
| 106 | + $j('#bodyContent').prepend( |
| 107 | + // Append switch visual / text editor links |
| 108 | + $j('<div />') |
| 109 | + .append( |
| 110 | + $j.button({ |
| 111 | + 'icon' : 'video', |
| 112 | + 'text' : gM( "mwe-sequencer-visual-editor") |
| 113 | + }).click( function(){ |
| 114 | + $j('#sequencerContainer').show(); |
| 115 | + $j('#editform').hide(); |
| 116 | + }), |
| 117 | + $j.button({ |
| 118 | + 'icon' : 'script' |
| 119 | + 'text' : gM("mwe-sequencer-text-editor-warn") |
| 120 | + }).click(function(){ |
| 121 | + $j('#sequencerContainer').hide(); |
| 122 | + $j('#editform').show(); |
| 123 | + }), |
| 124 | + $j('<div />') |
| 125 | + .css({ |
| 126 | + 'width' : '100%', |
| 127 | + 'height' : '700px' |
| 128 | + }) |
| 129 | + .attr({ |
| 130 | + 'id', 'sequencerContainer' |
| 131 | + }) |
| 132 | + ) |
| 133 | + ); |
| 134 | + // load the sequence editor with the sequencerContainer target |
| 135 | + mw.load( 'Sequencer', function(){ |
| 136 | + $j('#sequencerContainer').sequencer( _this.getSequencerConfig() ); |
| 137 | + }); |
| 138 | + }, |
| 139 | + |
| 140 | + |
76 | 141 | getSequenceFileKey: function( wgPageName ){ |
77 | 142 | return 'File:' + wgPageName.replace( 'Sequence:', 'Sequence-') + '.ogv'; |
78 | 143 | }, |
| 144 | + |
79 | 145 | displayPlayerEmbed: function(){ |
80 | 146 | var _this = this; |
81 | 147 | // load the embedPlayer module: |
— | — | @@ -88,6 +154,7 @@ |
89 | 155 | 'iiurlwidth': '400', |
90 | 156 | 'redirects' : true // automatically follow redirects |
91 | 157 | }; |
| 158 | + |
92 | 159 | var $embedPlayer = $j('<div />'); |
93 | 160 | mw.getJSON( request, function( data ){ |
94 | 161 | if(!data.query || !data.query.pages || data.query.pages[-1]){ |
— | — | @@ -152,13 +219,14 @@ |
153 | 220 | ) |
154 | 221 | } |
155 | 222 | } |
| 223 | + var width = ( imageinfo.thumbwidth )?imageinfo.thumbwidth : '400px'; |
156 | 224 | // Display embed sequence |
157 | 225 | $j( _this.target ).empty().append( |
158 | 226 | $j('<div />') |
159 | 227 | .addClass( 'sequencer-player') |
160 | 228 | .css( { |
161 | 229 | 'float' : 'left', |
162 | | - 'width' : imageinfo.thumbwidth |
| 230 | + 'width' : width |
163 | 231 | }) |
164 | 232 | .append( |
165 | 233 | $embedPlayer |
— | — | @@ -194,7 +262,7 @@ |
195 | 263 | ), |
196 | 264 | |
197 | 265 | // Add a clear both to give content body height |
198 | | - $j('<div />').css({'clear': 'both'}) |
| 266 | + $j('<div />').css( { 'clear': 'both' } ) |
199 | 267 | ) |
200 | 268 | // Rewrite the player |
201 | 269 | $j('#embedSequencePlayer').embedPlayer(); |
— | — | @@ -226,38 +294,42 @@ |
227 | 295 | ) |
228 | 296 | .css( {'width':'200px', 'margin':'auto'}) |
229 | 297 | ) |
230 | | - ) |
231 | | - |
232 | | - mw.load( 'Sequencer', function(){ |
233 | | - // Send a jquery ui style destroy command |
| 298 | + ) |
| 299 | + mw.load( 'Sequencer', function(){ |
| 300 | + var _this = this; |
| 301 | + // Send a jquery ui style destroy command ( in case the editor is re-invoked ) |
234 | 302 | $j('#edit_sequence_container').sequencer( 'destroy'); |
235 | | - $j('#edit_sequence_container').sequencer({ |
236 | | - // The title for this sequence: |
237 | | - title : _this.getTitle(), |
238 | | - // If the sequence is new |
239 | | - newSequence : ( wgArticleId == 0 ), |
240 | | - // Server config: |
241 | | - server: { |
242 | | - 'type' : 'mediaWiki', |
243 | | - 'url' : _this.getApiUrl(), |
244 | | - 'titleKey' : wgPageName, |
245 | | - }, |
246 | | - // Set the add media wizard to only include commons: |
247 | | - addMedia : { |
248 | | - 'enabled_providers':[ 'wiki_commons' ], |
249 | | - 'default_query' : _this.getTitle() |
250 | | - }, |
251 | | - // Function called on sequence exit |
252 | | - onExitCallback: function( sequenceHasChanged ){ |
253 | | - if( sequenceHasChanged ){ |
254 | | - window.location.reload(); |
255 | | - } |
256 | | - // else do nothing |
257 | | - } |
258 | | - }); |
| 303 | + $j('#edit_sequence_container').sequencer( _this.getSequencerConfig() ); |
259 | 304 | }); |
260 | 305 | }, |
261 | | - |
| 306 | + getSequencerConfig: function(){ |
| 307 | + var _this = this; |
| 308 | + return { |
| 309 | + // The title for this sequence: |
| 310 | + title : _this.getTitle(), |
| 311 | + // If the sequence is new |
| 312 | + newSequence : ( wgArticleId == 0 ), |
| 313 | + // Server config: |
| 314 | + server: { |
| 315 | + 'type' : 'mediaWiki', |
| 316 | + 'url' : _this.getApiUrl(), |
| 317 | + 'titleKey' : wgPageName, |
| 318 | + 'pagePathUrl' : wgServer + wgArticlePath |
| 319 | + }, |
| 320 | + // Set the add media wizard to only include commons: |
| 321 | + addMedia : { |
| 322 | + 'enabled_providers':[ 'wiki_commons' ], |
| 323 | + 'default_query' : _this.getTitle() |
| 324 | + }, |
| 325 | + // Function called on sequence exit |
| 326 | + onExitCallback: function( sequenceHasChanged ){ |
| 327 | + if( sequenceHasChanged ){ |
| 328 | + window.location.reload(); |
| 329 | + } |
| 330 | + // else do nothing |
| 331 | + } |
| 332 | + } |
| 333 | + }, |
262 | 334 | getApiTitleKey: function(){ |
263 | 335 | return wgTitle; |
264 | 336 | }, |
Index: branches/MwEmbedStandAlone/remotes/mediaWiki.js |
— | — | @@ -12,7 +12,10 @@ |
13 | 13 | window.console.log( 'mwEmbed:remote: ' + mwRemoteVersion ); |
14 | 14 | } |
15 | 15 | |
16 | | - |
| 16 | +// Make sure mw exists:: |
| 17 | +if( typeof window.mw == 'undefined'){ |
| 18 | + window.mw = {}; |
| 19 | +} |
17 | 20 | // Setup up request Params: |
18 | 21 | var reqParts = urlparts[1].substring( 1 ).split( '&' ); |
19 | 22 | var mwReqParam = { }; |
— | — | @@ -64,7 +67,6 @@ |
65 | 68 | } |
66 | 69 | } |
67 | 70 | |
68 | | - |
69 | 71 | // Use wikibits onLoad hook: ( since we don't have js2 / mw object loaded ) |
70 | 72 | addOnloadHook( function() { |
71 | 73 | doPageSpecificRewrite(); |
— | — | @@ -82,7 +84,7 @@ |
83 | 85 | window.ranMwRewrites = 'done'; |
84 | 86 | |
85 | 87 | // Add media wizard |
86 | | - if ( wgAction == 'edit' || wgAction == 'submit' ) { |
| 88 | + if ( ( wgAction == 'edit' && wgPageName.indexOf( "Sequence:" ) ) || wgAction == 'submit' ) { |
87 | 89 | loadMwEmbed( [ |
88 | 90 | 'mw.RemoteSearchDriver', |
89 | 91 | 'mw.ClipEdit', |
— | — | @@ -120,12 +122,21 @@ |
121 | 123 | } |
122 | 124 | |
123 | 125 | // Remote Sequencer |
124 | | - if( wgPageName.indexOf( "Sequence:" ) === 0 ){ |
| 126 | + if( wgPageName.indexOf( "Sequence:" ) === 0 ){ |
125 | 127 | //console.log( 'spl: ' + typeof mwSetPageToLoading ); |
126 | 128 | // If on a view page set content to "loading" |
127 | | - if( wgAction == 'view' ){ |
128 | | - mwSetPageToLoading(); |
| 129 | + if( wgAction == 'view' || wgAction == 'edit' ){ |
| 130 | + if( wgAction == 'view' ){ |
| 131 | + mwSetPageToLoading(); |
| 132 | + } |
| 133 | + if( wgAction == 'edit' ){ |
| 134 | + mwAddCommonStyleSheet(); |
| 135 | + var body = document.getElementById( 'bodyContent' ); |
| 136 | + body.innerHTML = "<div class=\"loadingSpinner\"></div>" + body.innerHTML; |
| 137 | + } |
129 | 138 | loadMwEmbed( [ 'mw.MediaWikiRemoteSequencer' ], function(){ |
| 139 | + $j('.loadingSpinner').remove(); |
| 140 | + $j('#editform').hide(); |
130 | 141 | var remote = new mw.MediaWikiRemoteSequencer({ |
131 | 142 | 'action': wgAction, |
132 | 143 | 'title' : wgTitle, |
— | — | @@ -211,12 +222,21 @@ |
212 | 223 | * Sets the mediaWiki content to "loading" |
213 | 224 | */ |
214 | 225 | function mwSetPageToLoading(){ |
215 | | - importStylesheetURI( mwEmbedHostPath + '/skins/mvpcf/EmbedPlayer.css?' + mwGetReqArgs() ); |
| 226 | + mwAddCommonStyleSheet(); |
216 | 227 | var body = document.getElementById('bodyContent'); |
217 | 228 | var oldBodyHTML = body.innerHTML; |
218 | | - body.innerHTML = '<div class="loadingSpinner"></div>'; |
| 229 | + body.innerHTML = '<div class="loadingSpinner"></div>'; |
219 | 230 | return oldBodyHTML; |
220 | 231 | } |
| 232 | +function mwAddCommonStyleSheet(){ |
| 233 | + importStylesheetURI( mwEmbedHostPath + '/skins/common/mw.style.mwCommon.css?' + mwGetReqArgs() ); |
| 234 | + // Set the style to defined ( so that when mw won't load the style sheet again) |
| 235 | + if( !mw.style ){ |
| 236 | + mw.style = { 'mwCommon' : true }; |
| 237 | + } else { |
| 238 | + mw.style['mwCommon'] = true; |
| 239 | + } |
| 240 | +} |
221 | 241 | /** |
222 | 242 | * Similar to the player loader in /modules/embedPlayer/loader.js |
223 | 243 | * ( front-loaded to avoid extra requests ) |