Index: branches/MwEmbedStandAlone/mwEmbed.js |
— | — | @@ -1027,7 +1027,10 @@ |
1028 | 1028 | * dialogHtml text Html of the loader msg |
1029 | 1029 | */ |
1030 | 1030 | mw.addLoaderDialog = function( dialogHtml ) { |
1031 | | - $dialog = mw.addDialog( { |
| 1031 | + if( typeof dialogHtml == 'undefined'){ |
| 1032 | + dialogHtml =''; |
| 1033 | + } |
| 1034 | + var $dialog = mw.addDialog( { |
1032 | 1035 | 'title' : dialogHtml, |
1033 | 1036 | 'content' : dialogHtml + '<br>' + |
1034 | 1037 | $j('<div />') |
— | — | @@ -1045,7 +1048,12 @@ |
1046 | 1049 | if( !mw.isset( '$j.ui.dialog' ) ) { |
1047 | 1050 | return false; |
1048 | 1051 | } |
1049 | | - $j( '#mwTempLoaderDialog' ).dialog( 'destroy' ).remove(); |
| 1052 | + // Close with timeout since jquery ui binds with timeout: |
| 1053 | + // ui dialog line 530 |
| 1054 | + setTimeout( function(){ |
| 1055 | + $j( '#mwTempLoaderDialog' ) |
| 1056 | + .dialog( 'destroy' ); |
| 1057 | + } , 10); |
1050 | 1058 | } |
1051 | 1059 | |
1052 | 1060 | /** |
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBody.js |
— | — | @@ -50,8 +50,10 @@ |
51 | 51 | */ |
52 | 52 | assignIds: function( $node ) { |
53 | 53 | var _this = this; |
| 54 | + // Don't give ids to nodes that have id's or are of type param |
54 | 55 | if( !$node.attr('id') |
55 | 56 | && !$node.attr( 'xml:id' ) |
| 57 | + && _this.getNodeSmilType( $node ).toLowerCase() != 'param' |
56 | 58 | ){ |
57 | 59 | var idString = _this.getNodeSmilType( $node ) + '_' + _this.idIndex; |
58 | 60 | // Make sure the id does not already exist ( should be a rare case ) |
Index: branches/MwEmbedStandAlone/modules/SwarmTransport/loader.js |
— | — | @@ -33,7 +33,7 @@ |
34 | 34 | // If the swarm transport is enabled add mw.SwarmTransport to the request. |
35 | 35 | if( mw.getConfig( 'SwarmTransport.enable' ) ) { |
36 | 36 | if( $j.inArray( 'mw.SwarmTransport', classRequest ) == -1 ) { |
37 | | - classRequest.push( 'mw.SwarmTransport' ); |
| 37 | + classRequest.push( [ 'mw.SwarmTransport' ]); |
38 | 38 | } |
39 | 39 | } |
40 | 40 | }); |
Index: branches/MwEmbedStandAlone/modules/AddMedia/searchLibs/mediaWikiSearch.js |
— | — | @@ -183,14 +183,18 @@ |
184 | 184 | } |
185 | 185 | |
186 | 186 | // Get the url safe titleKey from the descriptionurl |
187 | | - var titleKey = page.imageinfo[0].descriptionurl.split( '/' ); |
188 | | - titleKey = unescape( titleKey[ titleKey.length - 1 ] ); |
| 187 | + var titleKey = page.imageinfo[0].descriptionurl.split( '/' ) |
| 188 | + ; |
| 189 | + titleKey = unescape( |
| 190 | + titleKey[ titleKey.length - 1 ] |
| 191 | + .replace( 'index.php?title=', '') |
| 192 | + ); |
189 | 193 | |
190 | 194 | var resource = { |
191 | 195 | 'id' : page_id, |
192 | 196 | 'titleKey' : titleKey, |
193 | 197 | 'link' : page.imageinfo[0].descriptionurl, |
194 | | - 'title' : page.title.replace(/File:|.jpg|.png|.svg|.ogg|.ogv|.oga/ig, ''), |
| 198 | + 'title' : page.title.replace(/Image:|File:|.jpg|.png|.svg|.ogg|.ogv|.oga/ig, ''), |
195 | 199 | 'poster' : page.imageinfo[0].thumburl, |
196 | 200 | 'thumbwidth' : page.imageinfo[0].thumbwidth, |
197 | 201 | 'thumbheight': page.imageinfo[0].thumbheight, |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.RemoteSequencer.js |
— | — | @@ -1,120 +0,0 @@ |
2 | | -/** |
3 | | -* Stop-gap for php sequencer support does some transformations |
4 | | -* to normal page views to support sequences edits |
5 | | -* |
6 | | -* Supports basic "sequencer" functionality as a javascript rewrite system. |
7 | | -*/ |
8 | | - |
9 | | -mw.addMessageKeys( [ |
10 | | - "mwe-sequencer-no-sequence-create", |
11 | | - "mwe-sequencer-create-sequence" |
12 | | -]); |
13 | | - |
14 | | -mw.RemoteSequencer = function( options ) { |
15 | | - return this.init( options ); |
16 | | -}; |
17 | | -mw.RemoteSequencer.prototype = { |
18 | | - /** |
19 | | - * @constructor |
20 | | - * @param {Object} options RemoteMwSequencer options |
21 | | - */ |
22 | | - init: function( options ) { |
23 | | - this.action = ( options.action )? options.action : this.action; |
24 | | - this.title = ( options.title )? options.title : this.title; |
25 | | - this.target = ( options.target )? options.target : this.target; |
26 | | - }, |
27 | | - |
28 | | - drawUI: function() { |
29 | | - // Check page action |
30 | | - if( this.action == 'view' ) { |
31 | | - this.showViewUI(); |
32 | | - } |
33 | | - }, |
34 | | - /** |
35 | | - * Check page for sequence |
36 | | - * if not present give link to "create" one. |
37 | | - */ |
38 | | - showViewUI: function() { |
39 | | - var _this = this; |
40 | | - if( wgArticleId == 0 ) { |
41 | | - // Update create button |
42 | | - $j('#ca-edit span a') |
43 | | - .text( gM('mwe-sequencer-create-sequence' )) |
44 | | - .click(function(){ |
45 | | - _this.showEditor(); |
46 | | - }) |
47 | | - |
48 | | - $j( this.target ).html( |
49 | | - gM("mwe-sequencer-no-sequence-create", |
50 | | - $j('<a />').attr('href','#').click(function() { |
51 | | - _this.showEditor(); |
52 | | - }) |
53 | | - ) |
54 | | - ); |
55 | | - } else { |
56 | | - // Display embedding help |
57 | | - } |
58 | | - }, |
59 | | - showEditor: function(){ |
60 | | - var _this = this; |
61 | | - |
62 | | - $j('body').append( |
63 | | - $j('<div />') |
64 | | - .attr('id',"edit_sequence_container") |
65 | | - .css({ |
66 | | - 'position' : 'absolute', |
67 | | - 'font-size' : '.8em', |
68 | | - 'top' : '5px', |
69 | | - 'bottom' : '5px', |
70 | | - 'left' : '5px', |
71 | | - 'right' : '5px', |
72 | | - 'background': '#FFF' |
73 | | - }) |
74 | | - .loadingSpinner() |
75 | | - ) |
76 | | - |
77 | | - mw.load( 'Sequencer', function(){ |
78 | | - $j('#edit_sequence_container').sequencer({ |
79 | | - 'title' : _this.getTitle(), |
80 | | - 'newSequence' : ( wgArticleId == 0 ), |
81 | | - 'server': { |
82 | | - 'type' : 'mediaWiki', |
83 | | - 'url' : _this.getApiUrl(), |
84 | | - 'titleKey' : wgTitle, |
85 | | - }, |
86 | | - // Set the add media wizard to only include commons: |
87 | | - 'addMedia' : { |
88 | | - 'enabled_providers':[ 'wiki_commons' ], |
89 | | - 'default_query' : _this.getTitle() |
90 | | - } |
91 | | - }); |
92 | | - }); |
93 | | - }, |
94 | | - |
95 | | - getApiTitleKey: function(){ |
96 | | - return wgTitle; |
97 | | - }, |
98 | | - getTitle: function(){ |
99 | | - return wgTitle.replace( 'Sequence:', '').replace('_', ' '); |
100 | | - }, |
101 | | - // Get the api url ( for now use whatever the page context is ) |
102 | | - getApiUrl: function(){ |
103 | | - return mw.absoluteUrl( wgScript.replace('index.php', 'api.php') ); |
104 | | - }, |
105 | | - |
106 | | - // Check page type |
107 | | - |
108 | | - // "view" page |
109 | | - |
110 | | - // set page content to "loading" |
111 | | - // get wikitext of page via api |
112 | | - // grab xml |
113 | | - // update page with sequence and |
114 | | - |
115 | | - |
116 | | - //"edit" page |
117 | | - // grab textbox text, |
118 | | - // set page to loading |
119 | | - // display sequence editor in "body" with -> full-screen link |
120 | | -}; //Setup the remote configuration |
121 | | - |
\ No newline at end of file |
Index: branches/MwEmbedStandAlone/modules/Sequencer/loader.js |
— | — | @@ -11,6 +11,7 @@ |
12 | 12 | |
13 | 13 | "mw.SequencerConfig" : "mw.SequencerConfig.js", |
14 | 14 | |
| 15 | + "mw.SequencerServer" : "mw.SequencerServer.js", |
15 | 16 | "mw.SequencerAddMedia" : "mw.SequencerAddMedia.js", |
16 | 17 | "mw.SequencerPlayer" : "mw.SequencerPlayer.js", |
17 | 18 | "mw.SequencerTimeline" : "mw.SequencerTimeline.js", |
— | — | @@ -27,7 +28,7 @@ |
28 | 29 | "mw.FirefoggRender" : "mw.FirefoggRender.js", |
29 | 30 | "$j.fn.layout" : "ui.layout/ui.layout-1.2.0.js", |
30 | 31 | |
31 | | - "mw.RemoteSequencer" : "mw.RemoteSequencer.js", |
| 32 | + "mw.MediaWikiRemoteSequencer" : "remotes/mw.MediaWikiRemoteSequencer.js", |
32 | 33 | "mw.style.Sequencer" : "css/mw.style.Sequencer.css" |
33 | 34 | |
34 | 35 | } ); |
— | — | @@ -55,6 +56,7 @@ |
56 | 57 | [ |
57 | 58 | '$j.contextMenu', |
58 | 59 | |
| 60 | + 'mw.SequencerServer', |
59 | 61 | 'mw.SequencerAddMedia', |
60 | 62 | 'mw.SequencerPlayer', |
61 | 63 | 'mw.SequencerRender', |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.Sequencer.js |
— | — | @@ -161,6 +161,7 @@ |
162 | 162 | * @param {function} callback Function called with smilSource |
163 | 163 | */ |
164 | 164 | getSmilSource: function( callback ){ |
| 165 | + var _this = this; |
165 | 166 | if( !this.smilSource ){ |
166 | 167 | if( this.getOption( 'newSequence' ) ){ |
167 | 168 | this.smilSource = this.getDataUrl( this.getNewSmilXML() ); |
— | — | @@ -168,8 +169,8 @@ |
169 | 170 | mw.log("Load smil source from server") |
170 | 171 | // Try to load from the server |
171 | 172 | this.getServer().getSmilXml(function( smilXml ){ |
172 | | - this.smilSource = this.getDataUrl( smilXml ); |
173 | | - callback( this.smilSource ) |
| 173 | + _this.smilSource = _this.getDataUrl( smilXml ); |
| 174 | + callback( _this.smilSource ) |
174 | 175 | }) |
175 | 176 | // Wait for server to return smil source |
176 | 177 | return ; |
Index: branches/MwEmbedStandAlone/modules/Sequencer/Sequencer.i18n.php |
— | — | @@ -29,10 +29,14 @@ |
30 | 30 | 'mwe-sequencer-clip-duration' => 'Clip duration', |
31 | 31 | |
32 | 32 | 'mwe-sequencer-save-sequence' => 'Save sequence', |
| 33 | + 'mwe-sequencer-loading_user_rights' => 'Loading user rights ...', |
33 | 34 | 'mwe-sequencer-sequence-xml' => 'Sequence smil xml', |
34 | 35 | 'mwe-sequencer-render-sequence' => 'Render sequence to file', |
35 | 36 | 'mwe-sequencer-create-sequence' => 'Create sequence', |
| 37 | + 'mwe-sequencer-edit-sequence' => 'Edit sequence', |
36 | 38 | |
| 39 | + 'mwe-sequencer-embed-sequence' => 'Embed Sequence into article', |
| 40 | + 'mwe-sequencer-embed-sequence-desc' => 'Copy the following code into an article to embed this sequence', |
37 | 41 | |
38 | 42 | 'mwe-sequencer-menu-sequence' => 'Sequence', |
39 | 43 | 'mwe-sequencer-menu-sequence-new' => 'New', |
— | — | @@ -44,6 +48,7 @@ |
45 | 49 | 'mwe-sequencer-menu-sequence-save' => 'Save Sequence', |
46 | 50 | 'mwe-sequencer-menu-sequence-publish' => 'Publish', |
47 | 51 | 'mwe-sequencer-menu-sequence-renderdisk' => 'Render to disk', |
| 52 | + 'mwe-sequencer-menu-sequence-exit' => 'Exit', |
48 | 53 | |
49 | 54 | 'mwe-sequencer-menu-edit' => 'Edit', |
50 | 55 | 'mwe-sequencer-menu-edit-undo' => 'Undo', |
— | — | @@ -59,6 +64,20 @@ |
60 | 65 | 'mwe-sequencer-insert-resource' => 'Insert resource into sequence', |
61 | 66 | 'mwe-sequencer-insert'=> 'Insert into sequence', |
62 | 67 | |
| 68 | + 'mwe-sequencer-no-server-defined' => 'No server has been defined for this sequence session. You will not be able to save sequences', |
| 69 | + 'mwe-sequencer-no_edit_permissions' => 'You do not have permissions to save changes to this sequence', |
| 70 | + 'mwe-sequencer-save-summary' => 'Please enter a short summary of changes:', |
| 71 | + 'mwe-sequencer-edit_cancel' => 'Cancel sequence edit', |
| 72 | + |
| 73 | + 'mwe-sequencer-edit_save' => 'Save sequence changes', |
| 74 | + 'mwe-sequencer-saving_wait' => 'Save in progress (please wait)', |
| 75 | + 'mwe-sequencer-save_done' => 'Save complete', |
| 76 | + |
| 77 | + |
| 78 | + 'mwe-sequencer-not-published' => 'This sequence has not yet been published. <i>Browser preview is shown</i>. [$1 Publish this sequence]', |
| 79 | + 'mwe-sequencer-published-out-of-date' =>'This sequence has not yet been published. <i>Version $1 is shown</i>. [$2 Publish update]', |
| 80 | + |
| 81 | + |
63 | 82 | 'mwe-sequencer-transition_in' => 'Transition in', |
64 | 83 | 'mwe-sequencer-transition_out' => 'Transition out', |
65 | 84 | 'mwe-sequencer-effects' => 'Effects stack', |
— | — | @@ -71,13 +90,10 @@ |
72 | 91 | 'mwe-sequencer-menu_cliplib' => 'Add media', |
73 | 92 | 'mwe-sequencer-menu_resource_overview' => 'Resource overview', |
74 | 93 | 'mwe-sequencer-menu_options' => 'Options', |
75 | | - 'mwe-sequencer-loading_user_rights' => 'Loading user rights ...', |
76 | | - 'mwe-sequencer-no_edit_permissions' => 'You do not have permissions to save changes to this sequence', |
| 94 | + |
77 | 95 | |
78 | | - 'mwe-sequencer-edit_save' => 'Save sequence changes', |
79 | | - 'mwe-sequencer-saving_wait' => 'Save in progress (please wait)', |
80 | | - 'mwe-sequencer-save_done' => 'Save complete', |
81 | | - 'mwe-sequencer-edit_cancel' => 'Cancel sequence edit', |
| 96 | + |
| 97 | + |
82 | 98 | 'mwe-sequencer-edit_cancel_confirm' => 'Are you sure you want to cancel your edit? Changes will be lost.', |
83 | 99 | 'mwe-sequencer-zoom_in' => 'Zoom in', |
84 | 100 | 'mwe-sequencer-zoom_out' => 'Zoom out', |
Index: branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsSequence.js |
— | — | @@ -16,11 +16,71 @@ |
17 | 17 | this.sequencer = sequencer; |
18 | 18 | }, |
19 | 19 | save: function(){ |
| 20 | + var _this = this; |
20 | 21 | // Check if we have an api provider defined |
21 | | - if( this.sequencer.apiProvider ){ |
| 22 | + if( ! this.sequencer.getServer().exists() ){ |
| 23 | + mw.addDialog( gM('mwe-sequencer-no-server-defined') ) |
| 24 | + return ; |
| 25 | + } |
| 26 | + var $dialog = mw.addDialog({ |
| 27 | + 'resizable':'true', |
| 28 | + 'title' : gM('mwe-sequencer-loading_user_rights'), |
| 29 | + 'content' : gM('mwe-sequencer-loading_user_rights'), |
| 30 | + 'width' : 450 |
| 31 | + }); |
22 | 32 | |
23 | | - } |
24 | | - // No apiProvider show xml |
25 | | - |
26 | | - } |
| 33 | + // Check if we can save |
| 34 | + this.sequencer.getServer().userCanSave( function( canSave ){ |
| 35 | + if( canSave === false ){ |
| 36 | + $dialog.html( gM( 'mwe-sequencer-no_edit_permissions') ); |
| 37 | + // Add close text |
| 38 | + $dialog.dialog( "option", "closeText", gM('mwe-ok') ); |
| 39 | + return ; |
| 40 | + } |
| 41 | + _this.showSaveDialog( $dialog ); |
| 42 | + }); |
| 43 | + }, |
| 44 | + showSaveDialog: function( $dialog ){ |
| 45 | + var _this = this; |
| 46 | + // Else user 'can save' present a summary text box |
| 47 | + var saveDialogButtons = { }; |
| 48 | + saveDialogButtons[ gM('mwe-sequencer-edit_save') ] = function(){ |
| 49 | + $dialog.empty().append( |
| 50 | + gM('mwe-sequencer-saving_wait' ), |
| 51 | + $j('<div />').loadingSpinner() |
| 52 | + ); |
| 53 | + _this.doSaveWithSummary( $dialog.find('.saveSummary').val(), function( status, errorMsg ){ |
| 54 | + if( status === false ){ |
| 55 | + $dialog.text( errorMsg ) |
| 56 | + } else { |
| 57 | + // save success |
| 58 | + $dialog.text( gM( 'mwe-sequencer-save_done' ) ) |
| 59 | + } |
| 60 | + // Only let the user hit 'ok' |
| 61 | + var closeButton = {}; |
| 62 | + closeButton[gM('mwe-ok')]= function(){ $j(this).dialog('close') }; |
| 63 | + $dialog.dialog( "option", "buttons", closeButton); |
| 64 | + }); |
| 65 | + }; |
| 66 | + saveDialogButtons[ gM('mwe-sequencer-edit_cancel') ] = function(){ |
| 67 | + $dialog.dialog('close'); |
| 68 | + }; |
| 69 | + $dialog.empty().append( |
| 70 | + gM('mwe-sequencer-save-summary' ), |
| 71 | + $j('<input />') |
| 72 | + .css({'width': 400 }) |
| 73 | + .addClass( 'saveSummary' ) |
| 74 | + .attr({ |
| 75 | + 'maxlength': 255 |
| 76 | + }) |
| 77 | + ) |
| 78 | + .dialog( "option", "buttons", saveDialogButtons ); |
| 79 | + }, |
| 80 | + doSaveWithSummary : function( summary, callback ){ |
| 81 | + this.sequencer.getServer().save( |
| 82 | + summary, |
| 83 | + this.sequencer.getSmil().getXMLString(), |
| 84 | + callback |
| 85 | + ); |
| 86 | + } |
27 | 87 | } |
\ No newline at end of file |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerAddMedia.js |
— | — | @@ -28,7 +28,7 @@ |
29 | 29 | .val( |
30 | 30 | gM( 'mwe-sequencer-url-or-search') |
31 | 31 | ) |
32 | | - .css('color', '#888') |
| 32 | + .css({'color': '#888', 'zindex': 2}) |
33 | 33 | .focus( function(){ |
34 | 34 | // on the first focus clear the input and update the color |
35 | 35 | if( !widgetFocus ){ |
— | — | @@ -38,6 +38,9 @@ |
39 | 39 | } |
40 | 40 | widgetFocus = true; |
41 | 41 | }) |
| 42 | + .click(function(){ |
| 43 | + $j(this).focus(); |
| 44 | + }) |
42 | 45 | // add the sequencer input binding |
43 | 46 | .sequencerInput( _this.sequencer ) |
44 | 47 | ) |
— | — | @@ -188,10 +191,11 @@ |
189 | 192 | if( resource[i] ){ |
190 | 193 | $smilRef.attr( resourceAttributeMap[i], resource[i] ); |
191 | 194 | } |
192 | | - } |
| 195 | + } |
193 | 196 | var resourceParamMap = { |
194 | 197 | 'content_provider_id' : 'apiProvider', |
195 | | - 'id' : 'apiTitleKey' |
| 198 | + 'id' : 'id', |
| 199 | + 'titleKey' : 'apiTitleKey' |
196 | 200 | } |
197 | 201 | for( var i in resourceParamMap ){ |
198 | 202 | if( resource[i] ){ |
— | — | @@ -205,13 +209,13 @@ |
206 | 210 | } |
207 | 211 | } |
208 | 212 | // Make sure we have source for the asset. |
209 | | - if( $smilRef.attr('src') ){ |
| 213 | + if( $smilRef.attr('src') ){ |
210 | 214 | callback( $smilRef.get(0) ) |
211 | 215 | } else { |
212 | 216 | // the resource includes a pointer to its parent search object |
213 | 217 | // from the search object grab the image object for the target resolution |
214 | 218 | resource.pSobj.getImageObj( |
215 | | - resource, |
| 219 | + resource, |
216 | 220 | { |
217 | 221 | 'width' : mw.getConfig( 'Sequencer.AddMediaImageWidth' ) |
218 | 222 | }, |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerMenu.js |
— | — | @@ -47,6 +47,14 @@ |
48 | 48 | 'action' : function( _this ){ |
49 | 49 | _this.sequencer.getRender().renderDialog(); |
50 | 50 | } |
| 51 | + }, |
| 52 | + 'divider': true, |
| 53 | + 'exit' : { |
| 54 | + 'icon' : 'power', |
| 55 | + 'action' : function( _this ){ |
| 56 | + mw.log( 'check for save') |
| 57 | + _this.sequencer.getContainer().fadeOut().remove(); |
| 58 | + } |
51 | 59 | } |
52 | 60 | }, |
53 | 61 | 'edit':{ |
— | — | @@ -195,12 +203,12 @@ |
196 | 204 | $j('<li />') |
197 | 205 | .addClass('divider') |
198 | 206 | .append( $j('<hr />').css('width', '80%') ) |
199 | | - ); |
200 | | - continue; |
201 | | - } |
202 | | - $menu.append( |
203 | | - _this.getMenuItem( menuKey, menuItemKey ) |
204 | | - ) |
| 207 | + ); |
| 208 | + } else { |
| 209 | + $menu.append( |
| 210 | + _this.getMenuItem( menuKey, menuItemKey ) |
| 211 | + ) |
| 212 | + } |
205 | 213 | } |
206 | 214 | return $menu; |
207 | 215 | }, |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerTimeline.js |
— | — | @@ -355,7 +355,8 @@ |
356 | 356 | * Insert a smilClip to the smil dom and sequencer and display the edit |
357 | 357 | * interface with a 'cancel' insert button |
358 | 358 | */ |
359 | | - insertSmilClipEdit: function( smilClip, trackIndex, clipIndex ){ |
| 359 | + insertSmilClipEdit: function( smilClip, trackIndex, clipIndex ){ |
| 360 | + var _this = this; |
360 | 361 | // Handle optional arguments |
361 | 362 | if( typeof trackIndex == 'undefined' ){ |
362 | 363 | trackIndex = this.getSelectedTrackIndex(); |
Index: branches/MwEmbedStandAlone/modules/Sequencer/remotes/mw.MediaWikiRemoteSequencer.js |
— | — | @@ -0,0 +1,254 @@ |
| 2 | +/** |
| 3 | +* Stop-gap for php sequencer support does some transformations |
| 4 | +* to normal page views to support sequences edits |
| 5 | +* |
| 6 | +* Supports basic "sequencer" functionality as a javascript rewrite system. |
| 7 | +*/ |
| 8 | + |
| 9 | +mw.addMessageKeys( [ |
| 10 | + "mwe-sequencer-no-sequence-create", |
| 11 | + "mwe-sequencer-create-sequence", |
| 12 | + "mwe-sequencer-edit-sequence", |
| 13 | + "mwe-sequencer-embed-sequence", |
| 14 | + "mwe-sequencer-embed-sequence-desc", |
| 15 | + |
| 16 | + "mwe-sequencer-not-published", |
| 17 | + "mwe-sequencer-published-out-of-date" |
| 18 | +]); |
| 19 | + |
| 20 | +mw.MediaWikiRemoteSequencer = function( options ) { |
| 21 | + return this.init( options ); |
| 22 | +}; |
| 23 | +mw.MediaWikiRemoteSequencer.prototype = { |
| 24 | + /** |
| 25 | + * @constructor |
| 26 | + * @param {Object} options RemoteMwSequencer options |
| 27 | + */ |
| 28 | + init: function( options ) { |
| 29 | + this.action = ( options.action )? options.action : this.action; |
| 30 | + this.title = ( options.title )? options.title : this.title; |
| 31 | + this.target = ( options.target )? options.target : this.target; |
| 32 | + }, |
| 33 | + |
| 34 | + drawUI: function() { |
| 35 | + // Check page action |
| 36 | + if( this.action == 'view' ) { |
| 37 | + this.showViewUI(); |
| 38 | + } |
| 39 | + }, |
| 40 | + /** |
| 41 | + * Check page for sequence |
| 42 | + * if not present give link to "create" one. |
| 43 | + */ |
| 44 | + showViewUI: function() { |
| 45 | + var _this = this; |
| 46 | + if( wgArticleId == 0 ) { |
| 47 | + // Update create button |
| 48 | + $j('#ca-edit span a') |
| 49 | + .text( gM('mwe-sequencer-create-sequence' )) |
| 50 | + .click(function(){ |
| 51 | + _this.showEditor(); |
| 52 | + return false; |
| 53 | + }) |
| 54 | + |
| 55 | + $j( this.target ).html( |
| 56 | + gM("mwe-sequencer-no-sequence-create", |
| 57 | + $j('<a />').attr('href','#').click(function() { |
| 58 | + _this.showEditor(); |
| 59 | + return false; |
| 60 | + }) |
| 61 | + ) |
| 62 | + ); |
| 63 | + } else { |
| 64 | + // Update edit button |
| 65 | + $j('#ca-edit span a') |
| 66 | + .text( gM('mwe-sequencer-edit-sequence' )) |
| 67 | + .click(function(){ |
| 68 | + _this.showEditor(); |
| 69 | + return false; |
| 70 | + }) |
| 71 | + |
| 72 | + _this.displayPlayerEmbed(); |
| 73 | + } |
| 74 | + }, |
| 75 | + getSequenceFileKey: function( wgPageName ){ |
| 76 | + return 'File:' + wgPageName.replace( 'Sequence:', 'Sequence-') + '.ogv'; |
| 77 | + }, |
| 78 | + displayPlayerEmbed: function(){ |
| 79 | + var _this = this; |
| 80 | + |
| 81 | + // Check if the sequence has been flattened and is up to date: |
| 82 | + var request = { |
| 83 | + 'action': 'query', |
| 84 | + 'titles': _this.getSequenceFileKey( wgPageName ), |
| 85 | + 'prop': 'imageinfo|revisions', |
| 86 | + 'iiprop': 'url|metadata', |
| 87 | + 'iiurlwidth': '400', |
| 88 | + 'redirects' : true // automatically follow redirects |
| 89 | + }; |
| 90 | + var $embedPlayer = $j('<div />'); |
| 91 | + mw.getJSON( request, function( data ){ |
| 92 | + if(!data.query || !data.query.pages || data.query.pages[-1]){ |
| 93 | + // no flattened file found |
| 94 | + $embedPlayer.append( |
| 95 | + gM('mwe-sequencer-not-published') |
| 96 | + ) |
| 97 | + return ; |
| 98 | + } |
| 99 | + for( var pageId in data.query.pages) { |
| 100 | + var page = data.query.pages[ pageId ]; |
| 101 | + |
| 102 | + // Check that the file has a later revision than the |
| 103 | + // page. ( up to date sequences always are later than |
| 104 | + // the revision of the page saved ). |
| 105 | + if( page.revisions && page.revisions[0] ){ |
| 106 | + if( page.revisions[0].revid < wgCurRevisionId ){ |
| 107 | + // flattened file out of date |
| 108 | + $embedPlayer.append( |
| 109 | + gM('mwe-sequencer-published-out-of-date') |
| 110 | + ) |
| 111 | + } |
| 112 | + } |
| 113 | + if( page.imageinfo && page.imageinfo[0] ){ |
| 114 | + var imageinfo = page.imageinfo[0]; |
| 115 | + var duration = 0; |
| 116 | + for( var i=0;i< imageinfo.metadata.length; i++){ |
| 117 | + if( imageinfo.metadata[i].name == 'length' ){ |
| 118 | + duration = Math.round( |
| 119 | + imageinfo.metadata[i].value * 1000 |
| 120 | + ) / 1000; |
| 121 | + } |
| 122 | + } |
| 123 | + // Append a player to the embedPlayer target |
| 124 | + // -- special title key sequence name bound |
| 125 | + $embedPlayer.append( |
| 126 | + $j('<video />') |
| 127 | + .attr({ |
| 128 | + 'poster' : imageinfo.thumburl, |
| 129 | + 'durationHint' : duration, |
| 130 | + 'apiTitleKey' : page.title |
| 131 | + }) |
| 132 | + .css({ |
| 133 | + 'width': imageinfo.thumbwidth, |
| 134 | + 'height' : imageinfo.thumbheight |
| 135 | + }) |
| 136 | + .append( |
| 137 | + // ogg source |
| 138 | + $j('<source />') |
| 139 | + .attr({ |
| 140 | + 'type': 'video/ogg', |
| 141 | + 'src' : imageinfo.url |
| 142 | + }) |
| 143 | + ) |
| 144 | + ) |
| 145 | + } |
| 146 | + } |
| 147 | + }) |
| 148 | + |
| 149 | + |
| 150 | + // Display embed sequence |
| 151 | + $j( this.target ).empty().append( |
| 152 | + $j('<div />') |
| 153 | + .addClass( 'sequencer-player') |
| 154 | + .css( { |
| 155 | + 'float' : 'left', |
| 156 | + 'width' : '69%' |
| 157 | + }) |
| 158 | + .append( $embedPlayer ) |
| 159 | + , |
| 160 | + |
| 161 | + // Embed player |
| 162 | + $j('<div />') |
| 163 | + .addClass( 'sequencer-embed-helper') |
| 164 | + .css({ |
| 165 | + 'margin-left': '70%' |
| 166 | + }) |
| 167 | + |
| 168 | + // Text embed code |
| 169 | + .append( |
| 170 | + $j('<h3 />') |
| 171 | + .text( gM('mwe-sequencer-embed-sequence') ) |
| 172 | + , |
| 173 | + $j('<span />' ) |
| 174 | + .text( gM('mwe-sequencer-embed-sequence-desc') ) |
| 175 | + , |
| 176 | + $j('<br />'), |
| 177 | + $j('<textarea />') |
| 178 | + .css({ |
| 179 | + 'width' : '100%', |
| 180 | + 'height' : '200px' |
| 181 | + }).focus(function(){ |
| 182 | + $j(this).select(); |
| 183 | + }) |
| 184 | + .append( |
| 185 | + _this.getSequenceEmbedCode() |
| 186 | + ) |
| 187 | + ) |
| 188 | + ) |
| 189 | + }, |
| 190 | + getSequenceEmbedCode: function(){ |
| 191 | + return 'embed code here'; |
| 192 | + }, |
| 193 | + showEditor: function(){ |
| 194 | + var _this = this; |
| 195 | + |
| 196 | + $j('body').append( |
| 197 | + $j('<div />') |
| 198 | + .attr('id',"edit_sequence_container") |
| 199 | + .css({ |
| 200 | + 'position' : 'absolute', |
| 201 | + 'font-size' : '.8em', |
| 202 | + 'top' : '5px', |
| 203 | + 'bottom' : '5px', |
| 204 | + 'left' : '5px', |
| 205 | + 'right' : '5px', |
| 206 | + 'background': '#FFF' |
| 207 | + }) |
| 208 | + .loadingSpinner() |
| 209 | + ) |
| 210 | + |
| 211 | + mw.load( 'Sequencer', function(){ |
| 212 | + $j('#edit_sequence_container').sequencer({ |
| 213 | + 'title' : _this.getTitle(), |
| 214 | + 'newSequence' : ( wgArticleId == 0 ), |
| 215 | + 'server': { |
| 216 | + 'type' : 'mediaWiki', |
| 217 | + 'url' : _this.getApiUrl(), |
| 218 | + 'titleKey' : wgPageName, |
| 219 | + }, |
| 220 | + // Set the add media wizard to only include commons: |
| 221 | + 'addMedia' : { |
| 222 | + 'enabled_providers':[ 'wiki_commons' ], |
| 223 | + 'default_query' : _this.getTitle() |
| 224 | + } |
| 225 | + }); |
| 226 | + }); |
| 227 | + }, |
| 228 | + |
| 229 | + getApiTitleKey: function(){ |
| 230 | + return wgTitle; |
| 231 | + }, |
| 232 | + getTitle: function(){ |
| 233 | + return wgTitle.replace( 'Sequence:', '').replace('_', ' '); |
| 234 | + }, |
| 235 | + // Get the api url ( for now use whatever the page context is ) |
| 236 | + getApiUrl: function(){ |
| 237 | + return mw.absoluteUrl( wgScript.replace('index.php', 'api.php') ); |
| 238 | + } |
| 239 | + |
| 240 | + // Check page type |
| 241 | + |
| 242 | + // "view" page |
| 243 | + |
| 244 | + // set page content to "loading" |
| 245 | + // get wikitext of page via api |
| 246 | + // grab xml |
| 247 | + // update page with sequence and |
| 248 | + |
| 249 | + |
| 250 | + //"edit" page |
| 251 | + // grab textbox text, |
| 252 | + // set page to loading |
| 253 | + // display sequence editor in "body" with -> full-screen link |
| 254 | +}; //Setup the remote configuration |
| 255 | + |
\ No newline at end of file |
Property changes on: branches/MwEmbedStandAlone/modules/Sequencer/remotes/mw.MediaWikiRemoteSequencer.js |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 256 | + native |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerServer.js |
— | — | @@ -6,27 +6,93 @@ |
7 | 7 | |
8 | 8 | //Wrap in mw closure |
9 | 9 | ( function( mw ) { |
10 | | - |
11 | | -mw.SequencerServer = function( sequencer ) { |
12 | | - return this.init( sequencer ); |
13 | | -}; |
| 10 | + |
| 11 | + mw.SequencerServer = function( sequencer ) { |
| 12 | + return this.init( sequencer ); |
| 13 | + }; |
14 | 14 | |
15 | | -// Set up the SequencerServer prototype method object |
16 | | -mw.SequencerServer.prototype = { |
17 | | - init: function( sequencer ){ |
18 | | - this.sequencer = sequencer; |
19 | | - // Set local config from sequencer options |
20 | | - var serverConfig = this.sequencer.getOption( 'server' ); |
| 15 | + // Set up the SequencerServer prototype method object |
| 16 | + mw.SequencerServer.prototype = { |
| 17 | + |
| 18 | + // lazy init save token for the server config |
| 19 | + saveToken : null, |
21 | 20 | |
22 | | - // NOTE this should trigger an apiHandler once we have more than one api backend |
23 | | - this.apiType = serverConfig.type; |
24 | | - this.apiUrl = serverConfig.url; |
25 | | - this.titleKey = serverConfig.titleKey; |
26 | | - }, |
27 | | - getSmilXml: function( callback ){ |
28 | | - mw.getTitleText( this.titleKey, callback ) |
| 21 | + /** |
| 22 | + * init the sequencer |
| 23 | + */ |
| 24 | + init: function( sequencer ){ |
| 25 | + this.sequencer = sequencer; |
| 26 | + // Set local config from sequencer options |
| 27 | + var serverConfig = this.sequencer.getOption( 'server' ); |
| 28 | + |
| 29 | + // NOTE this should trigger an apiHandler once we have more than one api backend |
| 30 | + if( serverConfig ){ |
| 31 | + if( serverConfig.type ) |
| 32 | + this.apiType = serverConfig.type; |
| 33 | + if( serverConfig.url ) |
| 34 | + this.apiUrl = serverConfig.url; |
| 35 | + if( serverConfig.titleKey ) |
| 36 | + this.titleKey = serverConfig.titleKey; |
| 37 | + } |
| 38 | + }, |
| 39 | + |
| 40 | + // Check if the server exists / is configured |
| 41 | + exists: function( ){ |
| 42 | + if( ! this.apiUrl || ! this.titleKey ){ |
| 43 | + return false; |
| 44 | + } |
| 45 | + return true; |
| 46 | + }, |
| 47 | + |
| 48 | + /** |
| 49 | + * Check if the user in the current session can save to the server |
| 50 | + */ |
| 51 | + userCanSave: function( callback ){ |
| 52 | + this.getSaveToken( callback ); |
| 53 | + }, |
| 54 | + |
| 55 | + getSmilXml: function( callback ){ |
| 56 | + mw.getTitleText( this.apiUrl, this.titleKey, callback ) |
| 57 | + }, |
| 58 | + |
| 59 | + // Get a save token, if unable to do so return false |
| 60 | + getSaveToken: function( callback ){ |
| 61 | + var _this = this; |
| 62 | + if( this.saveToken != null ){ |
| 63 | + callback ( this.saveToken ); |
| 64 | + return ; |
| 65 | + } |
| 66 | + mw.getToken( this.apiUrl, this.titleKey, function( saveToken ){ |
| 67 | + _this.saveToken = saveToken; |
| 68 | + callback ( _this.saveToken ) |
| 69 | + }); |
| 70 | + }, |
| 71 | + // Save the sequence |
| 72 | + save: function( summary, sequenceXML, callback){ |
| 73 | + var _this = this; |
| 74 | + this.getSaveToken( function( token ){ |
| 75 | + if( !token ){ |
| 76 | + callback( false, 'could not get edit token') |
| 77 | + return ; |
| 78 | + } |
| 79 | + var request = { |
| 80 | + 'action' : 'edit', |
| 81 | + 'summary' : summary, |
| 82 | + 'title' : _this.titleKey, |
| 83 | + 'text' : sequenceXML, |
| 84 | + 'token': token |
| 85 | + }; |
| 86 | + mw.getJSON( _this.apiUrl, request, function( data ) { |
| 87 | + if( data.edit && data.edit.result == 'Success' ) { |
| 88 | + callback( true ); |
| 89 | + } else { |
| 90 | + // xxx Should have more error handling ( conflict version save etc ) |
| 91 | + callback( false, 'failed to save to server'); |
| 92 | + } |
| 93 | + }) |
| 94 | + }) |
| 95 | + } |
29 | 96 | } |
30 | | -} |
31 | 97 | |
32 | 98 | |
33 | 99 | } )( window.mw ); |
\ No newline at end of file |
Index: branches/MwEmbedStandAlone/remotes/mediaWiki.js |
— | — | @@ -4,7 +4,7 @@ |
5 | 5 | */ |
6 | 6 | var urlparts = getRemoteEmbedPath(); |
7 | 7 | var mwEmbedHostPath = urlparts[0]; |
8 | | -var mwRemoteVersion = 'r137'; |
| 8 | +var mwRemoteVersion = 'r139'; |
9 | 9 | var mwUseScriptLoader = true; |
10 | 10 | |
11 | 11 | // Log the mwRemote version makes it easy to debug cache issues |
— | — | @@ -124,8 +124,8 @@ |
125 | 125 | //console.log( 'spl: ' + typeof mwSetPageToLoading ); |
126 | 126 | // If on a view page set content to "loading" |
127 | 127 | mwSetPageToLoading(); |
128 | | - loadMwEmbed( [ 'mw.RemoteSequencer' ], function(){ |
129 | | - var remote = new mw.RemoteSequencer({ |
| 128 | + loadMwEmbed( [ 'mw.MediaWikiRemoteSequencer' ], function(){ |
| 129 | + var remote = new mw.MediaWikiRemoteSequencer({ |
130 | 130 | 'action': wgAction, |
131 | 131 | 'title' : wgTitle, |
132 | 132 | 'target' : '#bodyContent' |
— | — | @@ -274,9 +274,9 @@ |
275 | 275 | |
276 | 276 | tag_type = 'video'; |
277 | 277 | |
278 | | - // Check type: |
279 | | - var pwidth = $j( '#' + vidId ).width(); |
| 278 | + // Check type: |
280 | 279 | var $pimg = $j( '#' + vidId + ' img:first' ); |
| 280 | + var pwidth = $pimg.width(); |
281 | 281 | var imgSring = $pimg.attr('src').split('/').pop(); |
282 | 282 | if( $pimg.attr('src') && imgSring == 'play.png' || imgSring == 'fileicon-ogg.png' ){ |
283 | 283 | tag_type = 'audio'; |
— | — | @@ -347,7 +347,6 @@ |
348 | 348 | 'style="width:' + pwidth + 'px;height:' + pheight + 'px;">' + |
349 | 349 | '</video>'; |
350 | 350 | } |
351 | | - |
352 | 351 | |
353 | 352 | // If the video is part of a "gallery box" use light-box linker instead |
354 | 353 | if( $j( '#' + vidId ).parents( '.gallerybox' ).length ){ |