http://www.mediawiki.org/wiki/Special:Code/MediaWiki/71833
Revision: 71833
Author: dale
Date: 2010-08-28 00:48:57 +0000 (Sat, 28 Aug 2010)
Log Message:
-----------
improved remote sequencer page edit support ( incomplete commit msg )
Modified Paths:
--------------
branches/MwEmbedStandAlone/modules/Playlist/mw.Playlist.js
branches/MwEmbedStandAlone/modules/Playlist/mw.PlaylistHandlerMediaRss.js
branches/MwEmbedStandAlone/modules/Sequencer/Sequencer.i18n.php
branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsEdit.js
branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsSequence.js
branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerAddByUrl.js
branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerConfig.js
branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerKeyBindings.js
branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerMenu.js
branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerServer.js
branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerTimeline.js
branches/MwEmbedStandAlone/modules/Sequencer/remotes/mw.MediaWikiRemoteSequencer.js
branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBuffer.js
branches/MwEmbedStandAlone/mwEmbed.js
branches/MwEmbedStandAlone/remotes/mediaWiki.js
Modified: branches/MwEmbedStandAlone/modules/Playlist/mw.Playlist.js
===================================================================
--- branches/MwEmbedStandAlone/modules/Playlist/mw.Playlist.js 2010-08-28
00:38:28 UTC (rev 71832)
+++ branches/MwEmbedStandAlone/modules/Playlist/mw.Playlist.js 2010-08-28
00:48:57 UTC (rev 71833)
@@ -77,10 +77,10 @@
// Set the target to loadingSpinner:
$j( this.target ).empty().loadingSpinner();
- this.loadPlaylistHandler( function( playlistHandler ){
- mw.log("mw.Playlist::loaded playlist handler");
+ this.loadPlaylistHandler( function( sourceHandler ){
+ mw.log("mw.Playlist::loaded playlist set");
// Check if load failed or empty playlist
- if( _this.sourceHandler.getClipList().length == 0 ){
+ if( sourceHandler.getClipList().length == 0 ){
$j( _this.target ).empty().text(
gM('mwe-playlist-empty') )
return ;
}
@@ -88,56 +88,247 @@
// Empty the target and setup player and playerList divs
$j( _this.target )
.empty()
+ .css('position', 'relative' )
.append(
$j( '<span />' )
.addClass( 'media-rss-video-player')
.css({
'float' : 'left'
})
- ,
- $j( '<div />')
- .addClass(
'media-rss-video-list-wrapper' )
+ ,
+ $j( '<div />')
+ .addClass( 'media-rss-video-list' )
+ .attr('id', _this.id + '_videolist')
+ .css({
+ 'position' : 'absolute',
+ 'z-index' : '1',
+ 'overflow' : 'auto',
+ 'bottom': '0px',
+ 'right' : '0px'
+ })
+ .hide()
+ );
+
+ // Check if we have multiple playlist and setup the
list and bindings
+ if( _this.sourceHandler.hasMultiplePlaylists() ){
+ var playlistSet =
_this.sourceHandler.getPlaylistSet();
+
+ var $plListContainer =$j('<div />')
+ .addClass( 'playlistSet-container
ui-state-default ui-widget-header ui-corner-all' )
+ .css({
+ 'position' : 'absolute',
+ 'overflow' : 'hidden',
+ 'top' : '3px',
+ 'right' : '0px',
+ 'height' : '20px'
+ })
+ .append(
+ $j('<div />')
+ .addClass( 'playlistSet-list' )
+ .css("width", '2000px')
+ );
+ $j( _this.target ).append( $plListContainer );
+
+ var $plListSet = $j( _this.target ).find(
'.playlistSet-list' );
+
+ $j.each( playlistSet, function( inx, playlist){
+ // add a divider
+ if( inx != 0 ){
+ $plListSet.append( $j('<span
/>').text( ' | ') )
+ }
+ $plListSet.append(
+ $j('<a />')
+ .attr('href', '#')
+ .text( playlist.name )
+ .click( function(){
+
_this.sourceHandler.setPlaylistIndex( inx );
+ $j(
_this.target + ' .media-rss-video-list').loadingSpinner();
+
_this.loadPlaylist( function(){
+ $j(
_this.target + ' .media-rss-video-list').empty();
+
_this.addMediaList();
+ });
+ return false;
+ })
+ .buttonHover()
+ )
+ });
+ // Check playlistSet width and add scroll left
/ scroll right buttons
+ if( $plListSet.width() >
$plListContainer.width() ){
+ var baseButtonWidth = 24;
+ $plListSet.css( {
+ 'position': 'absolute',
+ 'left' : baseButtonWidth + 'px'
+ });
+ var $scrollButton = $j('<div />')
+ .addClass( 'ui-corner-all
ui-state-default' )
.css({
- 'position' : 'relative',
- 'z-index' : '1',
- 'width': '400px',
- 'height': '300px',
- 'overflow' : 'auto'
+ 'position' : 'absolute',
+ 'top' : '-1px',
+ 'cursor' : 'pointer',
+ 'margin' :'0px',
+ 'padding' : '2px',
+ 'width' : '16px',
+ 'height' : '16px'
})
+
+ var $buttonSpan = $j('<span />')
+ .addClass( 'ui-icon' )
+ .css('margin', '2px' );
+
+ var plScrollPos = 0;
+ var scrollToListPos = function( pos ){
+
+ listSetLeft =
$plListSet.find('a').eq( pos ).offset().left -
+
$plListSet.offset().left ;
+
+ mw.log("scroll to: " + pos + '
left: ' + listSetLeft);
+ $plListSet.animate({'left': -(
listSetLeft - baseButtonWidth) + 'px'} );
+ }
+
+ $plListContainer
.append(
- $j( '<div />')
- .addClass(
'media-rss-video-list' )
- .attr('id', _this.id +
'_videolist')
+ $scrollButton.clone()
+ .css('left', '0px')
+ .append(
$buttonSpan.clone().addClass('ui-icon-circle-arrow-w') )
+ .click( function(){
+ //slide right
+ if( plScrollPos >= 0){
+ mw.log("scroll
right");
+ plScrollPos--
+
scrollToListPos( plScrollPos );
+ }
+ })
+ .buttonHover(),
+
+ $scrollButton.clone()
+ .css('right', '0px')
+ .append(
$buttonSpan.clone().addClass('ui-icon-circle-arrow-e') )
+ .click( function(){
+ //slide left
+ if( plScrollPos <
$plListSet.find('a').length-1 ){
+ plScrollPos++;
+
scrollToListPos( plScrollPos );
+ }
+ })
+ .buttonHover()
)
- .hide()
- );
+ }
+ }
// Add the selectable media list
_this.addMediaList();
// Add the player
- _this.updatePlayer( _this.clipIndex, function(){
-
+ _this.updatePlayer( _this.clipIndex, function(){
// Update the list height ( vertical layout )
- if( _this.layout == 'vertical' ){
- var targetListHeight = ( $j(
_this.target ).height() - $j( _this.target + ' .media-rss-video-player'
).height() );
- $j( _this.target + '
.media-rss-video-list-wrapper' ).css( {
- 'height' : targetListHeight,
+ if( _this.layout == 'vertical' ){
+ $j( _this.target + '
.media-rss-video-list' ).css( {
+ 'top' : $j( _this.target + '
.media-rss-video-player' ).height() + 4,
'width' : '100%'
} )
+ // Add space for the multi-playlist
selector:
+ if(
_this.sourceHandler.hasMultiplePlaylists() ){
+ // also adjust
.playlistSet-container if present
+ $j( _this.target + '
.playlistSet-container').css( {
+ 'top' : $j(
_this.target + ' .media-rss-video-player' ).height() + 4
+ })
+ $j( _this.target + '
.media-rss-video-list' ).css({
+ 'top' : $j(
_this.target + ' .media-rss-video-player' ).height() + 26
+ })
+ }
+
} else {
- var targetListWidth = ( $j(
_this.target ).width() - $j( _this.target + ' .media-rss-video-player'
).width() );
- $j( _this.target + '
.media-rss-video-list-wrapper').css( {
- 'width' : targetListWidth,
- 'height' : '100%'
- } )
+ // Update horizontal layout
+ $j( _this.target + '
.media-rss-video-list').css( {
+ 'top' : '0px',
+ 'left' : $j( _this.target + '
.media-rss-video-player' ).width() + 4
+ } )
+ // Add space for the multi-playlist
selector:
+ if(
_this.sourceHandler.hasMultiplePlaylists() ){
+ $j( _this.target + '
.playlistSet-container').css( {
+ 'left' : $j(
_this.target + ' .media-rss-video-player' ).width() + 4
+ })
+ $j( _this.target + '
.media-rss-video-list').css( {
+ 'top' : '26px'
+ })
+ }
}
+ var $videoList = $j( _this.target + '
.media-rss-video-list' );
+ $videoList.show()
// show the video list and apply the swipe
binding
$j( _this.target
).find('.media-rss-video-list-wrapper').fadeIn();
if( mw.isMobileSafari() ){
+ // iScroll is buggy with current
version of iPad / iPhone use scroll buttons instead
+ /*
document.addEventListener('touchmove',
function(e){ e.preventDefault(); });
var myScroll = iScroll( _this.id +
'_videolist' );
setTimeout(function () {
myScroll.refresh(); }, 0);
+ */
+ // add space for scroll buttons:
+ var curTop = $j( _this.target + '
.media-rss-video-list' ).css('top');
+ if(!curTop) curTop = '0px';
+ $j( _this.target + '
.media-rss-video-list' ).css( {
+ 'position' : 'absolute',
+ 'height' : null,
+ 'top' : curTop,
+ 'bottom' : '30px',
+ 'right': '0px'
+ })
+ if( _this.layout == 'vertical' ){
+ $j( _this.target + '
.media-rss-video-list' ).css({
+ 'top' : $j(
_this.target + ' .media-rss-video-player' ).height()
+ })
+ }
+ // Add scroll buttons:
+ $j( _this.target ).append(
+ $j( '<div />').css({
+ 'position' : 'absolute',
+ 'bottom' : '0px',
+ 'right': '0px',
+ 'height' : '30px',
+ 'width' : $j(
_this.target + ' .media-rss-video-list').width()
+ })
+ .append(
+ $j.button({
+ 'text' :
'scroll down',
+ 'icon_id' :
'circle-arrow-s'
+ })
+ .css('float', 'right')
+ .click(function(){
+ var
clipListCount = $videoList.children().length;
+ var clipSize =
$videoList.children(':first').height();
+ var curTop =
$videoList.attr('scrollTop');
+
+ var targetPos =
curTop + (clipSize * 3);
+ if( targetPos >
clipListCount * clipSize ){
+
targetPos = ( clipListCount * ( clipSize -1 ) );
+ }
+ //mw.log("
animate to: " +curTop + ' + ' + (clipSize * 3) + ' = ' + targetPos );
+
$videoList.animate({'scrollTop': targetPos }, 500 );
+
+ return false;
+ }),
+ $j.button({
+ 'text' :
'scroll up',
+ 'icon_id' :
'circle-arrow-n'
+ })
+ .css('float', 'left')
+ .click(function(){
+ var
clipListCount = $videoList.children().length;
+ var clipSize =
$videoList.children(':first').height();
+ var curTop =
$videoList.attr('scrollTop');
+
+ var targetPos =
curTop - (clipSize * 3);
+ if( targetPos <
0 ){
+
targetPos = 0
+ }
+ mw.log("
animate to: " +curTop + ' + ' + (clipSize * 3) + ' = ' + targetPos );
+
$videoList.animate({'scrollTop': targetPos }, 500 );
+
+ return false;
+ })
+ )
+ )
}
});
@@ -191,16 +382,15 @@
// Build and output the title
var $title = $j('<div />' )
- .addClass( 'playlist-title')
+ .addClass( 'playlist-title ui-state-default
ui-widget-header ui-corner-all')
.css( {
+ 'top' : '0px',
'height' : _this.titleHeight,
- 'font-size' : '85%',
'width' : playerSize.width
} )
.text(
_this.sourceHandler.getClipTitle( clipIndex )
)
- .addClass( 'ui-state-default ui-widget-header' )
$j( _this.target + ' .media-rss-video-player'
).find('.playlist-title').remove( );
$j( _this.target + ' .media-rss-video-player' ).prepend( $title
);
@@ -281,25 +471,27 @@
// Update the video tag with the embedPlayer
$j.embedPlayers( function(){
- // Setup ondone playing binding to play next clip
- $j( '#mrss_' + _this.id + '_' + _this.clipIndex
).unbind('ended').bind( 'ended', function(event, onDoneActionObject ){
- // Play next clip
- if( _this.clipIndex + 1 <
_this.sourceHandler.getClipCount() ){
- // Update the onDone action object to
not run the base control done:
- onDoneActionObject.runBaseControlDone =
false;
- _this.clipIndex++;
-
- // update the player and play the next
clip
- _this.updatePlayer( _this.clipIndex,
function(){
- _this.play();
- })
-
- } else {
- mw.log("Reached end of playlist run
normal end action" );
- // Update the onDone action object to
not run the base control done:
- onDoneActionObject.runBaseControlDone =
true;
- }
- })
+ // Setup ondone playing binding to play next clip (if
autoContinue is true )
+ if( _this.sourceHandler.autoContinue == true ){
+ $j( '#mrss_' + _this.id + '_' + _this.clipIndex
).unbind('ended').bind( 'ended', function(event, onDoneActionObject ){
+ // Play next clip
+ if( _this.clipIndex + 1 <
_this.sourceHandler.getClipCount() ){
+ // Update the onDone action
object to not run the base control done:
+
onDoneActionObject.runBaseControlDone = false;
+ _this.clipIndex++;
+
+ // update the player and play
the next clip
+ _this.updatePlayer(
_this.clipIndex, function(){
+ _this.play();
+ })
+
+ } else {
+ mw.log("Reached end of playlist
run normal end action" );
+ // Update the onDone action
object to not run the base control done:
+
onDoneActionObject.runBaseControlDone = true;
+ }
+ })
+ }
// Run the callback if its set
if( callback ){
callback();
@@ -345,7 +537,7 @@
'alt' :
_this.sourceHandler.getClipTitle( inx ),
'src' :
_this.sourceHandler.getClipPoster( inx )
})
- .css( 'width',
_this.itemThumbWidth )
+ .css( 'width',
_this.itemThumbWidth + 'px')
),
$j( '<td />')
.text(
_this.sourceHandler.getClipTitle( inx ) ),
Modified:
branches/MwEmbedStandAlone/modules/Playlist/mw.PlaylistHandlerMediaRss.js
===================================================================
--- branches/MwEmbedStandAlone/modules/Playlist/mw.PlaylistHandlerMediaRss.js
2010-08-28 00:38:28 UTC (rev 71832)
+++ branches/MwEmbedStandAlone/modules/Playlist/mw.PlaylistHandlerMediaRss.js
2010-08-28 00:48:57 UTC (rev 71833)
@@ -7,6 +7,9 @@
// Set the media rss namespace
mediaNS: 'http://search.yahoo.com/mrss/',
+ // If playback should continue to the next clip on clip complete
+ autoContinue: true,
+
init: function ( Playlist ){
this.playlist = Playlist;
},
@@ -21,13 +24,24 @@
callback( this.$rss );
return ;
}
+
+ // Show an error if a cross domain request:
+ if( ! mw.isLocalDomain( this.getSrc() ) ) {
+ mw.log("Error: trying to get cross domain playlist
source: " + this.getSrc() );
+ }
+
// Note this only works with local sources
- $j.get( mw.absoluteUrl( this.playlist.src ), function( data ){
+ $j.get( mw.absoluteUrl( this.getSrc() ), function( data ){
_this.$rss = $j( data );
callback( _this.$rss );
});
},
-
+ hasMultiplePlaylists: function(){
+ return false;
+ },
+ getSrc: function(){
+ return this.playlist.src;
+ },
// Get clip count
getClipCount: function(){
if( !this.$rss ){
@@ -71,7 +85,7 @@
getClipPoster: function ( clipIndex ){
var $item = this.$rss.find('item').eq( clipIndex );
var mediaThumb = $item.get(0).getElementsByTagNameNS(
this.mediaNS, 'thumbnail' );
- mw.log( 'MEDIAthumb: ' + $j( mediaThumb ).attr('url' ) );
+ mw.log( 'mw.PlaylistMediaRss::getClipPoster: ' + $j( mediaThumb
).attr('url' ) );
if( mediaThumb && $j( mediaThumb ).attr('url' ) ){
return $j( mediaThumb ).attr('url' );
}
Modified: branches/MwEmbedStandAlone/modules/Sequencer/Sequencer.i18n.php
===================================================================
--- branches/MwEmbedStandAlone/modules/Sequencer/Sequencer.i18n.php
2010-08-28 00:38:28 UTC (rev 71832)
+++ branches/MwEmbedStandAlone/modules/Sequencer/Sequencer.i18n.php
2010-08-28 00:48:57 UTC (rev 71833)
@@ -9,6 +9,9 @@
$messages = array();
$messages['en'] = array(
'mwe-sequencer-loading-sequencer' => 'Loading sequencer ...',
+
+ 'mwe-sequencer-visual-editor'=> "Visual sequence editor",
+ 'mwe-sequencer-text-editor-warn'=> 'Text XML editor ( not recommended )
',
'mwe-sequencer-loading-timeline' => 'Loading timeline ...',
'mwe-sequencer-loading-player' => 'Loading player ...',
'mwe-sequencer-loading-menu' => 'Loading menu ...',
@@ -76,12 +79,14 @@
'mwe-sequencer-save-no-changes' => 'There are no new edits to save',
'mwe-sequencer-save-summary' => 'Please enter a short summary of
changes:',
- 'mwe-sequencer-edit_cancel' => 'Cancel sequence edit',
-
+ 'mwe-sequencer-edit_cancel' => 'Cancel sequence edit',
'mwe-sequencer-saving_wait' => 'Save in progress (please wait)',
'mwe-sequencer-save_done' => 'Save complete',
+ 'mwe-sequencer-open-summary' => "Enter the name of the sequence you
would like to open",
+
+
'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>.',
'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.',
Modified:
branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsEdit.js
===================================================================
---
branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsEdit.js
2010-08-28 00:38:28 UTC (rev 71832)
+++
branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsEdit.js
2010-08-28 00:48:57 UTC (rev 71833)
@@ -17,15 +17,15 @@
editStack : [],
// Store the edit index
- editIndex : 0,
+ editIndex : 0,
- // The numbers of undos supported
- numberOfUndos : mw.getConfig( 'Sequencer.numberOfUndos' ),
-
init: function( sequencer ) {
this.sequencer = sequencer;
},
-
+ // return the configured numbers of undos supported
+ getNumberOfUndos: function(){
+ return mw.getConfig( 'Sequencer.NumberOfUndos' );
+ },
selectAll: function(){
// Select all the items in the timeline
$target = this.sequencer.getTimeline().getTimelineContainer();
@@ -60,9 +60,15 @@
this.editStack = this.editStack.splice(0,
this.editIndex);
}
+ // Shift the undo index if we have hit our max undo size
+ if( this.editStack.length > this.getNumberOfUndos() ){
+ this.editStack = this.editStack.splice(0, 1 );
+ }
+
// @@TODO could save space to just compute the diff in JS and
store that
// ie: http://code.google.com/p/google-diff-match-patch/
// ( instead of the full xml text with "key-pages" every 10
edits or something like that.
+ // ( should non-block compress in workerThread / need
workerThread architecture )
this.editStack.push( currentXML );
// Update the editIndex
@@ -70,6 +76,7 @@
// Enable the undo option:
this.sequencer.getMenu().enableMenuItem( 'edit', 'undo' );
+ this.sequencer.getMenu().enableMenuItem( 'sequencer', 'save' );
},
/**
Modified:
branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsSequence.js
===================================================================
---
branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsSequence.js
2010-08-28 00:38:28 UTC (rev 71832)
+++
branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsSequence.js
2010-08-28 00:48:57 UTC (rev 71833)
@@ -15,6 +15,72 @@
init: function( sequencer ) {
this.sequencer = sequencer;
},
+
+ /**
+ * present an open dialog to the user, and open the sequence in a new
window
+ */
+ open: function(){
+ var _this = this;
+ var $content = $j('<div />').append(
+ gM('mwe-sequencer-open-summary' ),
+ $j('<input />')
+ .css({ 'width': 400 })
+ .attr({
+ 'id' : 'sequenceOpenNameInput',
+ 'maxlength': 255
+ })
+ // Make sure keys press does not affect the
sequencer interface
+ .sequencerInput( _this.sequencer )
+ );
+ // XXX todo we should have an autocomplete on sequence name!
+
+ var buttons = {};
+ buttons[ gM('mwe-cancel') ] = function(){ $j( this ).dialog(
'cancel' ) };
+
+ // For now just support server based open .. ideally we could
browse for file
+ var $dialog = mw.addDialog({
+ 'resizable':'true',
+ 'title' : gM('mwe-sequencer-menu-sequence-open-desc'),
+ 'content' : $content,
+ 'buttons' : buttons,
+ 'width' : 450
+ });
+ // Add a special open button
+ $dialog.parent().find( '.ui-dialog-buttonpane' ).prepend(
+ $j.button({
+ 'icon' : 'folder-open',
+ 'text' : gM('mwe-sequencer-menu-sequence-open')
+ })
+ // Match button layout
+ .css({
+ 'margin':'0.5em 0.4em 0.5em 0',
+ 'padding' : '0.2em 1.4em 0.3em'
+ })
+ .attr({
+ 'id' : 'sequenceOpenButton',
+ 'target' : '_new',
+ 'href' : '#'
+ }).click( function(){
+ // Update the link
+ $j(this).attr({
+ 'href':
+ mw.getRemoteSequencerLink(
+ mw.escapeQuotesHTML(
+
_this.sequencer.getServer().getSequenceViewUrl(
+
// ( Sequence: is automatically pre-appended with getSequencePageUrl
+
// ( don't use Sequence: in the title )
+
$j('#sequenceOpenNameInput').val().replace(/Sequence:/i, '')
+ )
+ )
+ )
+ });
+ // Close the dialog
+ $j(this).dialog( 'close' );
+ // Follow the link
+ return true;
+ })
+ )
+ },
save: function(){
var _this = this;
var $dialog = mw.addDialog({
@@ -66,7 +132,6 @@
);
// Remove buttons while loading
$dialog.dialog( "option", "buttons", {} );
- $dialog.dialog( "option", "title",
gM('mwe-sequencer-saving_wait' ) );
_this.sequencer.getServer().save(
/* Save summary */
@@ -194,8 +259,7 @@
.text("%"),
$j('<div />').attr( 'id', 'firefoggProgressbar')
- );
- $j('<div />').attr( 'id', 'firefoggProgressbar')
+ );
// Embed the player and continue application flow
$j('#publishVideoTarget').embedPlayer({
'controls' : false
@@ -212,9 +276,10 @@
progressPrecent +
'%'
)
- $j("#firefoggProgressbar").progressbar(
- "option", "value", Math.round(
progress * 100 )
- );
+ mw.log( "set progrees to: " +
Math.round( progress * 100 ) );
+ $j("#firefoggProgressbar").progressbar({
+ "value" : Math.round( progress
* 100 )
+ });
},
'doneRenderCallback': function( fogg ){
_this.uploadRenderedVideo( $dialog,
fogg );
@@ -281,7 +346,7 @@
uploadDone: function($dialog, apiResult){
var _this = this;
// Check the api response
- if ( apiResult.error || ( apiResult.upload &&
+ if ( !apiResult || apiResult.error || ( apiResult.upload &&
( apiResult.upload.result == "Failure" ||
apiResult.upload.error ) ) ) {
$dialog.dialog( 'option', 'title',
gM('mwe-sequencer-publishing-error' ) );
@@ -292,12 +357,20 @@
// Success link to the sequence page / ok closes dialog
$dialog.dialog( 'option', 'title',
gM('mwe-sequencer-publishing-success' ) );
+ var button = {};
+ button[ gM('mwe-ok') ] = function(){
+ $j( this ).dialog('close')
+ };
+ $dialog.dialog( 'option', 'button', button );
+ // for some reason we lose button height :( (jquery bug ? )
+ $dialog.parent().css( 'height', $dialog.height() + 100 );
+
$dialog.empty().html(
gM('mwe-sequencer-publishing-success-desc',
$j('<a />')
.attr({
'target': '_new',
'href': wgArticlePath.replace( '$1', 'File:'
+_this.sequencer.getServer().getVideoFileName() )
- })
+ })
) );
// Update the buttons
var buttons = {};
Modified: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerAddByUrl.js
===================================================================
--- branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerAddByUrl.js
2010-08-28 00:38:28 UTC (rev 71832)
+++ branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerAddByUrl.js
2010-08-28 00:48:57 UTC (rev 71833)
@@ -28,7 +28,7 @@
* @param {Object} remoteSearchDriver The remote search driver
*/
addByUrlDialog: function( remoteSearchDriver, url ){
- // see if the asset matches the key type of any enabled content
provider:
+ // See if the asset matches the detailsUrl key type of any
enabled content provider:
$j.each( remoteSearchDriver.getEnabledProviders(),
function(providerName, provider){
});
Modified: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerConfig.js
===================================================================
--- branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerConfig.js
2010-08-28 00:38:28 UTC (rev 71832)
+++ branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerConfig.js
2010-08-28 00:48:57 UTC (rev 71833)
@@ -13,9 +13,16 @@
mw.setDefaultConfig({
// If the sequencer should attribute kaltura
"Sequencer.KalturaAttribution" : true,
-
+
+ // If a the sequencer should open new windows
+ "Sequencer.SpawnNewWindows" : true,
+
+ // If a the sequencer should include withJS=MediaWiki:mwEmbed in
created urls
+ // ( save gards ) against users that are 'trying' the
+ "Sequencer.WithJsMwEmbedUrlHelper" : true,
+
// The size of the undo stack
- "Sequencer.numberOfUndos" : 100,
+ "Sequencer.NumberOfUndos" : 100,
// Default image duration
"Sequencer.AddMediaImageDuration" : 2,
Modified:
branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerKeyBindings.js
===================================================================
--- branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerKeyBindings.js
2010-08-28 00:38:28 UTC (rev 71832)
+++ branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerKeyBindings.js
2010-08-28 00:48:57 UTC (rev 71833)
@@ -25,37 +25,12 @@
// set of key flags:
shiftDown: false,
ctrlDown: false,
-
+ /* events */
+
init: function( sequencer ){
this.sequencer = sequencer;
this.setupKeyBindigs()
},
-
- bindEvent: function( eventType, callback){
- if( typeof eventType == 'object' ){
- for( var i in eventType ){
- this.bindEvent( i, eventType[i] );
- }
- }
- switch( eventType ){
- case 'copy':
- this.copyEvent = callback;
- break;
- case 'cut':
- this.cutEvent = callback;
- break;
- case 'paste' :
- this.pasteEvent = callback;
- break;
- case 'escape' :
- this.escapeEvent = callback;
- break;
- case 'delete':
- this.deleteEvent = callback;
- break;
- }
- return this;
- },
onFocus: function( ){
this.inputFocus = true;
},
@@ -74,14 +49,14 @@
_this.ctrlDown = true;
if ( ( e.which == 67 && _this.ctrlDown ) &&
!_this.inputFocus )
- _this.copyEvent();
+ $j( _this ).trigger( 'copy ');
if ( ( e.which == 88 && _this.ctrlDown ) &&
!_this.inputFocus )
- _this.cutEvent();
+ $j( _this ).trigger( 'cut ');
// Paste cips on v + ctrl while not focused on a text
area:
if ( ( e.which == 86 && _this.ctrlDown ) &&
!_this.inputFocus )
- _this.pasteEvent();
+ $j( _this ).trigger( 'paste ');
} );
$j( window ).keyup( function( e ) {
@@ -95,12 +70,12 @@
// Escape key ( deselect )
if ( e.which == 27 )
- _this.escapeEvent();
+ $j( _this ).trigger( 'escape' );
// Backspace or Delete key while not focused on a text
area:
if ( ( e.which == 8 || e.which == 46 ) &&
!_this.inputFocus )
- _this.deleteEvent();
+ $j( _this ).trigger( 'delete' );
} );
}
Modified: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerMenu.js
===================================================================
--- branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerMenu.js
2010-08-28 00:38:28 UTC (rev 71832)
+++ branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerMenu.js
2010-08-28 00:48:57 UTC (rev 71833)
@@ -36,6 +36,7 @@
'save_divider': 'divider',
'save' : {
'icon' : 'disk',
+ 'disabled' : true,
'shortCut' : 'ctrl S',
'action' : function( _this ){
mw.log("SequencerMenu::save");
Modified: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerServer.js
===================================================================
--- branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerServer.js
2010-08-28 00:38:28 UTC (rev 71832)
+++ branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerServer.js
2010-08-28 00:48:57 UTC (rev 71833)
@@ -26,6 +26,9 @@
// The sequence title key for api queries
titleKey: null,
+ // The Url path the the sequence page with $1 where the title
should be
+ pagePathUrl: null,
+
// Stores the most recent version of the sequence xml from the
server
serverSmilXml: null,
@@ -42,12 +45,20 @@
// NOTE this should trigger an apiHandler once we have
more than one api backend
if( serverConfig ){
+
if( serverConfig.type )
this.apiType = serverConfig.type;
+
if( serverConfig.url )
this.apiUrl = serverConfig.url;
+
if( serverConfig.titleKey )
this.titleKey = serverConfig.titleKey;
+
+ if( serverConfig.pagePathUrl ){
+ this.pagePathUrl =
serverConfig.pagePathUrl;
+ }
+
}
if( this.isConfigured() ){
mw.log("Error: Sequencer server needs a full
serverConfig to be initialized")
@@ -200,6 +211,32 @@
});
},
/**
+ * Get the sequence description page url
+ * @param {String} Optional Sequence title key
+ */
+ getSequenceViewUrl: function( titleKey ){
+ if( !titleKey )
+ titleKey = this.titleKey;
+ // Check that we have a pagePathUrl config:
+ if( !this.pagePathUrl ){
+ return false;
+ }
+ return this.pagePathUrl.replace( '$1', 'Sequence:' +
titleKey);
+ },
+ /**
+ * Get the sequencer 'edit' url
+ */
+ getSequenceEditUrl: function( titleKey ){
+ if( !titleKey )
+ titleKey = this.titleKey;
+ // Check that we have a pagePathUrl config:
+ if( !this.pagePathUrl ){
+ return false;
+ }
+ return this.pagePathUrl.replace( '$1', 'Sequence:' +
titleKey);
+ },
+
+ /**
* Get the video file name for saving the flat video asset to
the server
* @return {String}
*/
Modified: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerTimeline.js
===================================================================
--- branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerTimeline.js
2010-08-28 00:38:28 UTC (rev 71832)
+++ branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerTimeline.js
2010-08-28 00:48:57 UTC (rev 71833)
@@ -212,14 +212,21 @@
// Add global TrackClipInterface bindings:
var keyBindings = this.sequencer.getKeyBindings();
- keyBindings.bindEvent({
- 'escape': function(){
- _this.getTimelineContainer().find(
'.selectedClip' ).removeClass( 'selectedClip' );
- },
- 'delete': function(){
+ $j( keyBindings ).bind('escape', function(){
+ // If a clips are selected deselect
+ var selectedClips = _this.getTimelineContainer().find(
'.selectedClip' )
+ if( selectedClips.length ){
+ selectedClips.removeClass( 'selectedClip' );
+ return;
+ }
+ // Else trigger an exit request
+ _this.sequencer.getActionsSequence().exit();
+ // stop event propagation
+ return false;
+ });
+ $j( keyBindings ).bind('delete', function(){
_this.removeSelectedClips();
- }
- })
+ });
},
getTrackSetId:function( trackIndex ){
Modified:
branches/MwEmbedStandAlone/modules/Sequencer/remotes/mw.MediaWikiRemoteSequencer.js
===================================================================
---
branches/MwEmbedStandAlone/modules/Sequencer/remotes/mw.MediaWikiRemoteSequencer.js
2010-08-28 00:38:28 UTC (rev 71832)
+++
branches/MwEmbedStandAlone/modules/Sequencer/remotes/mw.MediaWikiRemoteSequencer.js
2010-08-28 00:48:57 UTC (rev 71833)
@@ -13,10 +13,34 @@
"mwe-sequencer-embed-sequence-desc",
"mwe-sequencer-loading-sequencer",
+ "mwe-sequencer-visual-editor",
+ "mwe-sequencer-text-editor-warn",
+
+
"mwe-sequencer-not-published",
"mwe-sequencer-published-out-of-date"
]);
+/* exported functions */
+
+/**
+ * Special wrapper for sequence links when in 'extension' mode
+ * there is no need for js rewrite helpers
+ *
+ * @param {String} url The url to be wrapped
+ */
+mw.getRemoteSequencerLink = function( url ){
+ if( mw.getConfig( 'Sequencer.WithJsMwEmbedUrlHelper' ) ){
+ if( url.indexOf('?') == -1){
+ url+='?'
+ } else {
+ url+='&'
+ }
+ url+='withJS=MediaWiki:MwEmbed.js';
+ }
+ return url;
+},
+
mw.MediaWikiRemoteSequencer = function( options ) {
return this.init( options );
};
@@ -29,14 +53,17 @@
this.action = ( options.action )? options.action : this.action;
this.title = ( options.title )? options.title : this.title;
this.target = ( options.target )? options.target : this.target;
- },
+ },
drawUI: function() {
// Check page action
if( this.action == 'view' ) {
this.showViewUI();
}
- },
+ if( this.action == 'edit' ){
+ this.showEditUI();
+ }
+ },
/**
* Check page for sequence
* if not present give link to "create" one.
@@ -72,9 +99,48 @@
_this.displayPlayerEmbed();
}
},
+
+ showEditUI: function(){
+
+ $j('#bodyContent').prepend(
+ // Append switch visual / text editor links
+ $j('<div />')
+ .append(
+ $j.button({
+ 'icon' : 'video',
+ 'text' : gM(
"mwe-sequencer-visual-editor")
+ }).click( function(){
+ $j('#sequencerContainer').show();
+ $j('#editform').hide();
+ }),
+ $j.button({
+ 'icon' : 'script'
+ 'text' :
gM("mwe-sequencer-text-editor-warn")
+ }).click(function(){
+ $j('#sequencerContainer').hide();
+ $j('#editform').show();
+ }),
+ $j('<div />')
+ .css({
+ 'width' : '100%',
+ 'height' : '700px'
+ })
+ .attr({
+ 'id', 'sequencerContainer'
+ })
+ )
+ );
+ // load the sequence editor with the sequencerContainer target
+ mw.load( 'Sequencer', function(){
+ $j('#sequencerContainer').sequencer(
_this.getSequencerConfig() );
+ });
+ },
+
+
getSequenceFileKey: function( wgPageName ){
return 'File:' + wgPageName.replace( 'Sequence:', 'Sequence-')
+ '.ogv';
},
+
displayPlayerEmbed: function(){
var _this = this;
// load the embedPlayer module:
@@ -88,6 +154,7 @@
'iiurlwidth': '400',
'redirects' : true // automatically follow
redirects
};
+
var $embedPlayer = $j('<div />');
mw.getJSON( request, function( data ){
if(!data.query || !data.query.pages ||
data.query.pages[-1]){
@@ -152,13 +219,14 @@
)
}
}
+ var width = ( imageinfo.thumbwidth
)?imageinfo.thumbwidth : '400px';
// Display embed sequence
$j( _this.target ).empty().append(
$j('<div />')
.addClass( 'sequencer-player')
.css( {
'float' : 'left',
- 'width' : imageinfo.thumbwidth
+ 'width' : width
})
.append(
$embedPlayer
@@ -194,7 +262,7 @@
),
// Add a clear both to give content
body height
- $j('<div />').css({'clear': 'both'})
+ $j('<div />').css( { 'clear': 'both' } )
)
// Rewrite the player
$j('#embedSequencePlayer').embedPlayer();
@@ -226,38 +294,42 @@
)
.css( {'width':'200px', 'margin':'auto'})
)
- )
-
- mw.load( 'Sequencer', function(){
- // Send a jquery ui style destroy command
+ )
+ mw.load( 'Sequencer', function(){
+ var _this = this;
+ // Send a jquery ui style destroy command ( in case the
editor is re-invoked )
$j('#edit_sequence_container').sequencer( 'destroy');
- $j('#edit_sequence_container').sequencer({
- // The title for this sequence:
- title : _this.getTitle(),
- // If the sequence is new
- newSequence : ( wgArticleId == 0 ),
- // Server config:
- server: {
- 'type' : 'mediaWiki',
- 'url' : _this.getApiUrl(),
- 'titleKey' : wgPageName,
- },
- // Set the add media wizard to only include commons:
- addMedia : {
- 'enabled_providers':[ 'wiki_commons' ],
- 'default_query' : _this.getTitle()
- },
- // Function called on sequence exit
- onExitCallback: function( sequenceHasChanged ){
- if( sequenceHasChanged ){
- window.location.reload();
- }
- // else do nothing
- }
- });
+ $j('#edit_sequence_container').sequencer(
_this.getSequencerConfig() );
});
},
-
+ getSequencerConfig: function(){
+ var _this = this;
+ return {
+ // The title for this sequence:
+ title : _this.getTitle(),
+ // If the sequence is new
+ newSequence : ( wgArticleId == 0 ),
+ // Server config:
+ server: {
+ 'type' : 'mediaWiki',
+ 'url' : _this.getApiUrl(),
+ 'titleKey' : wgPageName,
+ 'pagePathUrl' : wgServer + wgArticlePath
+ },
+ // Set the add media wizard to only include commons:
+ addMedia : {
+ 'enabled_providers':[ 'wiki_commons' ],
+ 'default_query' : _this.getTitle()
+ },
+ // Function called on sequence exit
+ onExitCallback: function( sequenceHasChanged ){
+ if( sequenceHasChanged ){
+ window.location.reload();
+ }
+ // else do nothing
+ }
+ }
+ },
getApiTitleKey: function(){
return wgTitle;
},
Modified: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBuffer.js
===================================================================
--- branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBuffer.js
2010-08-28 00:38:28 UTC (rev 71832)
+++ branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBuffer.js
2010-08-28 00:48:57 UTC (rev 71833)
@@ -162,7 +162,9 @@
switch( this.smil.getRefType( smilElement ) ){
case 'video':
var vid = $j( '#' + this.smil.getPageDomId(
smilElement ) ).get(0);
-
+ if( !vid ){
+ break;
+ }
// The load request does not work very well
instead .play() then .pause() and seek when on display
// vid.load();
@@ -170,10 +172,8 @@
if( vid.paused && this.getVideoPercetLoaded(
smilElement ) == 0 ){
// Issue the load / play request
vid.play();
- vid.volume = 0;
-
- // XXX seek to clipBegin if provided (
we don't need to load before that point )
-
+ vid.volume = 0;
+ // XXX seek to clipBegin if provided (
we don't need to load before that point )
} else {
//mw.log("loadElement:: pause video: "
+ this.smil.getPageDomId( smilElement ));
// else we have some percentage loaded
pause playback
Modified: branches/MwEmbedStandAlone/mwEmbed.js
===================================================================
--- branches/MwEmbedStandAlone/mwEmbed.js 2010-08-28 00:38:28 UTC (rev
71832)
+++ branches/MwEmbedStandAlone/mwEmbed.js 2010-08-28 00:48:57 UTC (rev
71833)
@@ -47,7 +47,9 @@
mw.validSkins = [ 'mvpcf', 'kskin' ];
// Storage variable for loaded style sheet keys
- mw.style = { };
+ if( ! mw.style ){
+ mw.style = { };
+ }
/**
* Configuration System:
Modified: branches/MwEmbedStandAlone/remotes/mediaWiki.js
===================================================================
--- branches/MwEmbedStandAlone/remotes/mediaWiki.js 2010-08-28 00:38:28 UTC
(rev 71832)
+++ branches/MwEmbedStandAlone/remotes/mediaWiki.js 2010-08-28 00:48:57 UTC
(rev 71833)
@@ -12,7 +12,10 @@
window.console.log( 'mwEmbed:remote: ' + mwRemoteVersion );
}
-
+// Make sure mw exists::
+if( typeof window.mw == 'undefined'){
+ window.mw = {};
+}
// Setup up request Params:
var reqParts = urlparts[1].substring( 1 ).split( '&' );
var mwReqParam = { };
@@ -64,7 +67,6 @@
}
}
-
// Use wikibits onLoad hook: ( since we don't have js2 / mw object loaded )
addOnloadHook( function() {
doPageSpecificRewrite();
@@ -82,7 +84,7 @@
window.ranMwRewrites = 'done';
// Add media wizard
- if ( wgAction == 'edit' || wgAction == 'submit' ) {
+ if ( ( wgAction == 'edit' && wgPageName.indexOf( "Sequence:" ) ) ||
wgAction == 'submit' ) {
loadMwEmbed( [
'mw.RemoteSearchDriver',
'mw.ClipEdit',
@@ -120,12 +122,21 @@
}
// Remote Sequencer
- if( wgPageName.indexOf( "Sequence:" ) === 0 ){
+ if( wgPageName.indexOf( "Sequence:" ) === 0 ){
//console.log( 'spl: ' + typeof mwSetPageToLoading );
// If on a view page set content to "loading"
- if( wgAction == 'view' ){
- mwSetPageToLoading();
+ if( wgAction == 'view' || wgAction == 'edit' ){
+ if( wgAction == 'view' ){
+ mwSetPageToLoading();
+ }
+ if( wgAction == 'edit' ){
+ mwAddCommonStyleSheet();
+ var body = document.getElementById(
'bodyContent' );
+ body.innerHTML = "<div
class=\"loadingSpinner\"></div>" + body.innerHTML;
+ }
loadMwEmbed( [ 'mw.MediaWikiRemoteSequencer' ],
function(){
+ $j('.loadingSpinner').remove();
+ $j('#editform').hide();
var remote = new mw.MediaWikiRemoteSequencer({
'action': wgAction,
'title' : wgTitle,
@@ -211,12 +222,21 @@
* Sets the mediaWiki content to "loading"
*/
function mwSetPageToLoading(){
- importStylesheetURI( mwEmbedHostPath + '/skins/mvpcf/EmbedPlayer.css?'
+ mwGetReqArgs() );
+ mwAddCommonStyleSheet();
var body = document.getElementById('bodyContent');
var oldBodyHTML = body.innerHTML;
- body.innerHTML = '<div class="loadingSpinner"></div>';
+ body.innerHTML = '<div class="loadingSpinner"></div>';
return oldBodyHTML;
}
+function mwAddCommonStyleSheet(){
+ importStylesheetURI( mwEmbedHostPath +
'/skins/common/mw.style.mwCommon.css?' + mwGetReqArgs() );
+ // Set the style to defined ( so that when mw won't load the style
sheet again)
+ if( !mw.style ){
+ mw.style = { 'mwCommon' : true };
+ } else {
+ mw.style['mwCommon'] = true;
+ }
+}
/**
* Similar to the player loader in /modules/embedPlayer/loader.js
* ( front-loaded to avoid extra requests )
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs