r46886 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r46885‎ | r46886 | r46887 >
Date:00:37, 6 February 2009
Author:dale
Status:deferred
Tags:
Comment:
* reorganisation of clip edit lib
* more flexible language init system
* cleaned up core mv_embed a bit
** moved base Embed lib outside of mv_embed.js
Modified paths:
  • /trunk/extensions/MetavidWiki/skins/mv_embed/example_usage/sample_playlists.php (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/example_usage/sample_timed_text.php (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/mv_remote_media_search.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/mv_upload.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libClipEdit (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libClipEdit/mv_clipedit.js (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libEmbedObj/mv_baseEmbed.js (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libEmbedObj/mv_quicktimeEmbed.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libSequencer/mv_clipedit.js (deleted) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libSequencer/mv_sequencer.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libTimedText/mv_timed_text.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/mv_embed.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/mv_embed_iframe.php (modified) (history)

Diff [purge]

Index: trunk/extensions/MetavidWiki/skins/mv_embed/example_usage/sample_timed_text.php
@@ -1,3 +1,8 @@
 2+<?
 3+do_sample_page();
 4+
 5+function do_sample_page(){
 6+?>
27 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
38 "http://www.w3.org/TR/html4/loose.dtd">
49 <html>
@@ -48,4 +53,6 @@
4954 } ?>
5055 </table>
5156 </body>
52 -</html>
\ No newline at end of file
 57+</html>
 58+<?
 59+} ?>
\ No newline at end of file
Index: trunk/extensions/MetavidWiki/skins/mv_embed/example_usage/sample_playlists.php
@@ -1,4 +1,7 @@
22 <?php
 3+do_sample_page();
 4+
 5+function do_sample_page(){
36 // sample embed page (this could be plain html its a php script so that we can grab its location)
47 $mv_path = 'http://' . $_SERVER['SERVER_NAME'] . substr( $_SERVER['REQUEST_URI'], 0, strrpos( $_SERVER['REQUEST_URI'], '/' ) ) . '/';
58 $mv_path = str_replace( 'example_usage/', '', $mv_path );
@@ -79,3 +82,6 @@
8083 <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />&nbsp;
8184 </body>
8285 </html>
 86+<?
 87+}
 88+?>
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/mv_upload.js
@@ -3,16 +3,19 @@
44 will be replaced with upload API once that is ready
55 */
66
7 -gMsg['upload-enable-converter'] = 'Enable video converter (to upload source video not yet converted to theora format)'+
8 - ' <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">more info</a>';
9 -gMsg['upload-fogg_not_installed'] = 'If you want to upload video consider installing <a href="http://firefogg.org">firefogg.org</a>, '+
10 - '<a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">more info</a>';
11 -gMsg['upload-in-progress'] = 'Doing Transcode & Upload (do not close this window)';
12 -gMsg['upload-transcoded-status'] = 'Transcoded';
13 -gMsg['uploaded-status'] = 'Uploaded';
14 -gMsg['upload-select-file'] = 'Select File...';
15 -gMsg['wgfogg_wrong_version'] = 'You have firefogg installed but its outdated, <a href="http://firefogg.org">please upgrade</a> ';
16 -gMsg['wgfogg_waring_ogg_upload'] = 'You have selected an ogg file for conversion to ogg (this is probably unessesary). Maybe disable the video converter?';
 7+loadGM( {
 8+ 'upload-enable-converter' : 'Enable video converter (to upload source video not yet converted to theora format)',
 9+ ' <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">more info</a>',
 10+ 'upload-fogg_not_installed': 'If you want to upload video consider installing <a href="http://firefogg.org">firefogg.org</a>, '+
 11+ '<a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">more info</a>',
 12+ 'upload-in-progress':'Doing Transcode & Upload (do not close this window)',
 13+ 'upload-transcoded-status': 'Transcoded',
 14+ 'uploaded-status':'Uploaded',
 15+ 'upload-select-file': 'Select File...',
 16+ 'wgfogg_wrong_version': 'You have firefogg installed but its outdated, <a href="http://firefogg.org">please upgrade</a> ',
 17+ 'wgfogg_waring_ogg_upload': 'You have selected an ogg file for conversion to ogg (this is probably unessesary). Maybe disable the video converter?'
 18+ }
 19+);
1720
1821 var default_upload_options = {
1922 'target_div':'',
@@ -99,32 +102,32 @@
100103 $j('#mw-upload-table .mw-input').eq(0).html('<div id="wg-base-upload">' + itd_html + '</div>');
101104 //add in firefogg control
102105 $j('#wg-base-upload').after('<p id="fogg-enable-item" >' +
103 - '<input style="display:none" id="fogg-video-file" name="fogg-video-file" type="button" value="' + getMsg('upload-select-file') + '">' +
 106+ '<input style="display:none" id="fogg-video-file" name="fogg-video-file" type="button" value="' + gM('upload-select-file') + '">' +
104107 "<span class='error' id='wgfogg_not_installed'>" +
105 - getMsg('upload-fogg_not_installed') +
 108+ gM('upload-fogg_not_installed') +
106109 '</span>'+
107110 "<span class='error' id='wgfogg_wrong_version'>"+
108 - getMsg('wgfogg_wrong_version')+
 111+ gM('wgfogg_wrong_version')+
109112 '</span>'+
110113 "<span class='error' id='wgfogg_waring_ogg_upload' style='display:none' >"+
111 - getMsg('wgfogg_waring_ogg_upload')+
 114+ gM('wgfogg_waring_ogg_upload')+
112115 '</span>'+
113116 "<span id='wgfogg_installed' style='display:none' >"+
114117 '<input id="wgEnableFirefogg" type="checkbox" name="wgEnableFirefogg" >' +
115 - getMsg('upload-enable-converter') +
 118+ gM('upload-enable-converter') +
116119 '<span><br></p>');
117120 //add in loader dl box:
118121 //hard code style (since not always easy to import style sheets)
119122 $j('[@name=wpUpload]').eq(0).before('<div id="dlbox-centered" class="dlbox-centered" style="display:none;'+
120123 'position:fixed;background:#DDD;border:3px solid #AAA;font-size:115%;width:40%;'+
121124 'height:50%;padding: 10px;z-index:100;top:30%;left:15%;" >'+
122 - '<h5>' + getMsg('upload-in-progress') + '</h5>' +
 125+ '<h5>' + gM('upload-in-progress') + '</h5>' +
123126 '<div id="fogg-pbar-container" style="border:solid thin gray;width:90%;height:15px;" >' +
124127 '<div id="fogg-progressbar" style="background:#AAC;width:0%;height:15px;"></div>' +
125128 '</div>' +
126129 '<span id="fogg-pstatus">0%</span>' +
127 - '<span id="fogg-status-transcode">' + getMsg('upload-transcoded-status') + '</span>'+
128 - '<span style="display:none" id="fogg-status-upload">' + getMsg('uploaded-status') + '</span>' +
 130+ '<span id="fogg-status-transcode">' + gM('upload-transcoded-status') + '</span>'+
 131+ '<span style="display:none" id="fogg-status-upload">' + gM('uploaded-status') + '</span>' +
129132 '</div>'+
130133 '<div id="dlbox-overlay" class="dlbox-overlay" style="display:none;background:#000;cursor:wait;height:100%;'+
131134 'left:0;top:0;position:fixed;width:100%;z-index:99;filter:alpha(opacity=60);'+
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/mv_remote_media_search.js
@@ -7,18 +7,17 @@
88 metavid
99 and archive.org
1010 */
 11+loadGM( { 'mv_media_search' : 'Media Search',
 12+ 'rsd_box_layout' : 'Box layout',
 13+ 'rsd_list_layout' : 'List Layout',
 14+ 'rsd_results_desc' : 'Results ',
 15+ 'rsd_results_next' : 'next ',
 16+ 'rsd_results_prev' : 'previous ',
 17+ 'upload' : 'Upload',
 18+ 'rsd_layout' : 'Layout:',
 19+ 'rsd_resource_edit' : 'Edit Resource:'
 20+});
1121
12 -gMsg['mv_media_search'] = 'Media Search';
13 -gMsg['rsd_box_layout'] = 'Box layout';
14 -gMsg['rsd_list_layout'] = 'List Layout';
15 -gMsg['rsd_results_desc']= 'Results ';
16 -gMsg['rsd_results_next'] = ' next ';
17 -gMsg['rsd_results_prev'] = ' previous ';
18 -gMsg['upload'] = 'Upload';
19 -
20 -gMsg['rsd_layout'] = 'Layout:';
21 -gMsg['rsd_resource_edit']='Edit Resource:';
22 -
2322 var default_remote_search_options = {
2423 'profile':'mediawiki_edit',
2524 'target_id':null, //the div that will hold the search interface
@@ -203,7 +202,7 @@
204203 'size="20" autocomplete="off"/>'+
205204 '</td>'+
206205 '<td style="width:115px">'+
207 - '<input type="submit" value="' + getMsg('mv_media_search') + '" tabindex="2" '+
 206+ '<input type="submit" value="' + gM('mv_media_search') + '" tabindex="2" '+
208207 ' id="rms_search_button"/>'+
209208 '</td>'+
210209 '<td>';
@@ -230,7 +229,7 @@
231230 out+= '<img alt="'+cp.title+'" src="' + mv_embed_path + 'skins/' + mv_skin_name + '/images/remote_cp/' + cp_id + '_tab.png">';
232231 out+='</div>';
233232 }
234 - out+='<div style="clear:both"/><a id="mso_selprovider_close" href="#">'+getMsg('close')+'</a></div>';
 233+ out+='<div style="clear:both"/><a id="mso_selprovider_close" href="#">'+gM('close')+'</a></div>';
235234 out+='</div>';
236235 //close up the control container:
237236 out+='</div>';
@@ -372,7 +371,7 @@
373372 //do an upload tab if enabled:
374373 if( this.enable_uploads ){
375374 var class_attr = ( this.disp_item =='upload' ) ? 'class="rsd_selected"':'';
376 - o+='<li id="rsd_tab_upload" ' + class_attr + ' >'+getMsg('upload');+'</li>';
 375+ o+='<li id="rsd_tab_upload" ' + class_attr + ' >'+gM('upload');+'</li>';
377376 }
378377 o+='</ul>';
379378 o+='</div>';
@@ -434,7 +433,7 @@
435434 o+='<img title="'+rItem.title+'" class="rsd_res_item" id="res_' + rInx +'" style="width:' + _this.thumb_width + 'px;" src="' + rItem.poster + '">';
436435 //add a linkback to resource page in lower left:
437436 if(rItem.link)
438 - o+='<a target="_new" style="position:absolute;top:0px;right:0px" title="' + getMsg('Resource Description Page') + '" href="' + rItem.link + '"><img src="' + wgScriptPath + '/skins/common/images/magnify-clip.png"></a>';
 437+ o+='<a target="_new" style="position:absolute;top:0px;right:0px" title="' + gM('Resource Description Page') + '" href="' + rItem.link + '"><img src="' + wgScriptPath + '/skins/common/images/magnify-clip.png"></a>';
439438 o+='</div>';
440439 }else if(_this.result_display_mode == 'list'){
441440 o+='<div id="mv_result_' + rInx + '" class="mv_clip_list_result" style="' + disp + 'width:90%">';
@@ -486,7 +485,7 @@
487486 //append to the top level of model window:
488487 $j( '#'+ _this.target_id ).append('<div id="rsd_resource_edit" '+
489488 'style="position:absolute;top:0px;left:0px;width:100%;height:100%;background-color:#FFF;">' +
490 - '<h3 id="rsd_resource_title" style="margin:4px;">' + getMsg('rsd_resource_edit') + ' ' + rObj.title +'</h3>'+
 489+ '<h3 id="rsd_resource_title" style="margin:4px;">' + gM('rsd_resource_edit') + ' ' + rObj.title +'</h3>'+
491490 '<div id="clip_edit_disp" style="position:absolute;'+overflow_style+'top:30px;left:0px;bottom:0px;'+
492491 'width:' + (maxWidth + 30) + 'px;" >' +
493492 mv_get_loading_img('position:absolute;top:30px;left:30px', 'mv_img_loader') +
@@ -586,7 +585,7 @@
587586 'media_type': mediaType,
588587 'p_rsdObj': _this
589588 };
590 - var loadLibs = {'mvClipEdit':'libSequencer/mv_clipedit.js'};
 589+ var loadLibs = {'mvClipEdit':'libClipEdit/mv_clipedit.js'};
591590 if( mediaType == 'image'){
592591 //load the crop library:
593592 //loadLibs['$j.Jcrop']='jquery/plugins/Jcrop/js/jquery.Jcrop.js';
@@ -901,14 +900,14 @@
902901
903902 $j('#rsd_results').append('<div id="rds_results_bar">'+
904903 '<span style="position:relative;top:-5px;font-style:italic;">'+
905 - getMsg('rsd_layout')+' '+
 904+ gM('rsd_layout')+' '+
906905 '</span>'+
907906 '<img id="msc_box_layout" ' +
908 - 'title = "' + getMsg('rsd_box_layout') + '" '+
 907+ 'title = "' + gM('rsd_box_layout') + '" '+
909908 'src = "' + ( (_this.result_display_mode=='box')?box_dark_url:box_light_url ) + '" ' +
910909 'style="width:20px;height:20px;cursor:pointer;"> ' +
911910 '<img id="msc_list_layout" '+
912 - 'title = "' + getMsg('rsd_list_layout') + '" '+
 911+ 'title = "' + gM('rsd_list_layout') + '" '+
913912 'src = "' + ( (_this.result_display_mode=='list')?list_dark_url:list_light_url ) + '" '+
914913 'style="width:20px;height:20px;cursor:pointer;">'+
915914 '<span id="rsd_paging_ctrl" style="position:absolute;right:5px;"></span>'+
@@ -951,12 +950,12 @@
952951 var to_num = ( cp.limit > cp.sObj.num_results )?
953952 (cp.offset + cp.sObj.num_results):
954953 (cp.offset + cp.limit);
955 - var out = getMsg('rsd_results_desc') + (cp.offset+1) + ' to ' + to_num;
 954+ var out = gM('rsd_results_desc') + (cp.offset+1) + ' to ' + to_num;
956955 //check if we have more results (next prev link)
957956 if( cp.offset >= cp.limit )
958 - out+=' <a href="#" id="rsd_pprev">' + getMsg('rsd_results_prev') + cp.limit + '</a>';
 957+ out+=' <a href="#" id="rsd_pprev">' + gM('rsd_results_prev') + cp.limit + '</a>';
959958 if( cp.sObj.more_results )
960 - out+=' <a href="#" id="rsd_pnext">' + getMsg('rsd_results_next') + cp.limit + '</a>';
 959+ out+=' <a href="#" id="rsd_pnext">' + gM('rsd_results_next') + cp.limit + '</a>';
961960 $j(target).html(out);
962961 //set bindings
963962 $j('#rsd_pnext').click(function(){
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libSequencer/mv_clipedit.js
@@ -1,710 +0,0 @@
2 -/*
3 - hanndles clip edit controls
4 - 'inoutpoints':0, //should let you set the in and out points of clip
5 - 'panzoom':0, //should allow setting keyframes and tweening modes
6 - 'overlays':0, //should allow setting "locked to clip" overlay tracks
7 - 'audio':0 //should allow controlling the audio volume (with keyframes)
8 -*/
9 -
10 -gMsg['mv_crop']='Crop Image';
11 -gMsg['mv_apply_crop']='Apply Crop to Image';
12 -gMsg['mv_reset_crop']='Rest Crop';
13 -gMsg['mv_insert_image_page']='Insert Into page';
14 -gMsg['mv_preview_insert']= 'Preview Insert';
15 -gMsg['mv_cancel_image_insert']='Cancel Image Insert';
16 -
17 -gMsg['sc_fileopts'] ='Clip Detail Edit';
18 -gMsg['sc_inoutpoints'] ='Set In-Out points';
19 -gMsg['sc_panzoom'] ='Pan Zoom Crop';
20 -gMsg['sc_overlays'] ='Overlays';
21 -gMsg['sc_audio'] ='Audio Control';
22 -gMsg['sc_duration'] ='Duration';
23 -
24 -gMsg['mv_template_properties'] = 'Template Properties';
25 -gMsg['mv_custom_title'] = 'Custom Title';
26 -gMsg['mv_edit_properties'] = 'Edit Properties';
27 -gMsg['mv_other_properties'] = 'Other Properties';
28 -gMsg['mv_resource_page'] = 'Resource Page';
29 -
30 -var default_clipedit_values = {
31 - 'rObj': null, // the resource object
32 - 'clip_disp_ct':null,//target clip disp
33 - 'control_ct':null, //control container
34 - 'media_type': null, //media type
35 - 'parent_ct': null, //parent container
36 -
37 - 'p_rsdObj': null, //parent remote search object
38 - 'p_seqObj': null, //parent sequence Object
39 -
40 - 'edit_action': null, //the requested edit action
41 - 'profile': 'inpage' //the given profile either "inpage" or "sequence"
42 - //timeline invokes the timeline editor (letting you set keyframes)
43 -}
44 -var mvClipEdit = function(initObj) {
45 - return this.init(initObj);
46 -};
47 -mvClipEdit.prototype = {
48 -
49 - selTool:null, //selected tool
50 - crop: null, //the crop values
51 - base_img_src:null,
52 -
53 - init:function( initObj){
54 - //init object:
55 - for(var i in default_clipedit_values){
56 - if( initObj[i] ){
57 - this[i] = initObj[i];
58 - }
59 - }
60 -
61 - //if media type was not supplied detect for resoure if possible:
62 - //@@todo more advanced detection.
63 - if(!this.media_type){
64 - if( this.rObj.type.indexOf("image/") === 0){
65 - this.media_type = 'image';
66 - }else if( this.rObj.type.indexOf("video/") === 0){
67 - this.media_type = 'video';
68 - }else if( this.rObj.type.indexOf("text/") === 0){
69 - this.media_type = 'template';
70 - }
71 - }
72 -
73 - //display control:
74 - if(this.profile == 'sequence'){
75 - this.doEditTypesMenu();
76 - this.doDisplayEdit();
77 - }else{
78 - //check the media_type:
79 - js_log('mvClipEdit:: media type:' + this.media_type + ' base width: ' + this.rObj.width + ' bh: ' + this.rObj.height);
80 - //could seperate out into media Types objects for now just call method
81 - if(this.media_type == 'image'){
82 - this.setUpImageCtrl();
83 - }else if(this.media_type=='video'){
84 - this.setUpVideoCtrl();
85 - }
86 - }
87 - },
88 -
89 - //master edit types object:
90 - //maybe we should refactor these into their own classes
91 - //more refactor each media type should be its own class inheriting the shared baseEditType object
92 - edit_types:{
93 - 'fileopts':{
94 - 'd':1,
95 - 'media':['image','video','template'],
96 - 'doEdit':function( _this ){
97 - var doEditHtml = function(){
98 - //add html for rObj resource:
99 - var o= '<table>' +
100 - '<tr>' +
101 - '<td colspan="2"><b>'+getMsg('mv_edit_properties')+'</b></td>'+
102 - '</tr>'+
103 - '<tr>'+
104 - '<td>' +
105 - getMsg('mv_custom_title') +
106 - '</td>'+
107 - '<td><input type="text" size="15" maxwidth="255" value="';
108 - if(_this.rObj.title != null)
109 - o+=_this.rObj.title;
110 - o+='">'+
111 - '</td>'+
112 - '</tr>';
113 - if( _this.rObj.tVars){
114 - var existing_p = _this.rObj.params;
115 - var testing_a = _this.rObj.tVars;
116 - //debugger;
117 - o+= '<tr>'+
118 - '<td colspan="2"><b>'+getMsg('mv_template_properties')+'</b></td>'+
119 - '</tr>';
120 - for(var i =0; i < _this.rObj.tVars.length ; i++){
121 - o+='<tr>'+
122 - '<td>' +
123 - _this.rObj.tVars[i] +
124 - '</td>' +
125 - '<td><input type="text" size="15" maxwidth="255" value="';
126 - if(_this.rObj.params[ _this.rObj.tVars[i] ]){
127 - o+= _this.rObj.params[ _this.rObj.tVars[i] ];
128 - }
129 - o+='">'+
130 - '</td>'+
131 - '</tr>';
132 - }
133 - }
134 - o+= '<tr>'+
135 - '<td colspan="2"><b>'+getMsg('mv_other_properties')+'</b></td>'+
136 - '</tr>'+
137 - '<tr>'+
138 - '<td>' +
139 - getMsg('mv_resource_page') +
140 - '</td>' +
141 - '<td><a href="' + wgArticlePath.replace(/\$1/, _this.rObj.uri ) +
142 - ' target="new">'+
143 - _this.rObj.uri + '</a>'+
144 - '</td>'+
145 - '</tr>';
146 - o+='</table>';
147 -
148 - $j('#sub_cliplib_ic').html ( o );
149 - //add update bindings
150 -
151 - //update doFocusBindings
152 - if( _this.p_seqObj )
153 - _this.p_seqObj.doFocusBindings();
154 - }
155 - //if media type is template we have to query to get its URI to get its paramaters
156 - if(_this.media_type == 'template' && !_this.rObj.tVars){
157 - mv_set_loading('#sub_cliplib_ic');
158 - var reqObj ={ 'action':'query',
159 - 'prop':'revisions',
160 - 'titles': _this.rObj.uri,
161 - 'rvprop':'content'
162 - };
163 - //get the interface uri from the plObject
164 - var api_url = _this.p_seqObj.plObj.interface_url.replace(/index\.php/, 'api.php');
165 - //first check
166 - do_api_req( reqObj, api_url,function(data){
167 - if(typeof data.query.pages == 'undefined')
168 - return doEditHtml();
169 - for(var i in data.query.pages){
170 - var page = data.query.pages[i];
171 - var template_rev = page['revisions'][0]['*'];
172 - }
173 -
174 - //do a regular ex to get the ~likely~ template values
175 - //(ofcourse this sucks)
176 - //but maybe this will make its way into the api sometime soon to support wysiwyg type editors
177 - //idealy it would expose a good deal of info about the template params
178 - js_log('matching against: ' + template_rev);
179 - var tempVars = template_rev.match(/\{\{\{([^\}]*)\}\}\}/gi);
180 - //clean up results:
181 - _this.rObj.tVars = new Array();
182 - for(var i=0; i < tempVars.length; i++){
183 - var tvar = tempVars[i].replace('{{{','').replace('}}}','');
184 - //strip anything after a |
185 - if(tvar.indexOf('|') != -1){
186 - tvar = tvar.substr(0, tvar.indexOf('|'));
187 - }
188 - //check for duplicates:
189 - var do_add=true;
190 - for(var j=0; j < _this.rObj.tVars.length; j++){
191 - js_log('checking: ' + _this.rObj.tVars[j] + ' against:' + tvar);
192 - if( _this.rObj.tVars[j] == tvar)
193 - do_add=false;
194 - }
195 - //add the template vars to the output obj
196 - if(do_add)
197 - _this.rObj.tVars.push( tvar );
198 - }
199 - doEditHtml();
200 - });
201 - }else{
202 - doEditHtml();
203 - }
204 -
205 -
206 - }
207 - },
208 - 'duration':{
209 - d:0,
210 - 'media':['image','template'],
211 - 'doEdit':function( _this ){
212 - //do clock mouse scroll duration editor
213 - $j('#sub_cliplib_ic').html('cur dur: ' + _this.rObj.dur );
214 - }
215 - },
216 - 'inoutpoints':{
217 - 'd':0,
218 - 'media':['video'],
219 - 'doEdit':function( _this ){
220 - var cat = _this.rObj
221 - //debugger;
222 - //do clock mouse scroll duration editor
223 - var end_ntp = ( _this.rObj.embed.end_ntp) ? _this.rObj.embed.end_ntp : _this.rObj.embed.getDuration();
224 - if(!end_ntp)
225 - end_ntp = seconds2ntp( _this.rObj.dur );
226 - $j('#sub_cliplib_ic').html(
227 - _this.getSetInOut({
228 - 'start_ntp' : _this.rObj.embed.start_ntp,
229 - 'end_ntp' : end_ntp
230 - })
231 - );
232 - _this.setInOutBindings();
233 - }
234 - },
235 - 'panzoom':{
236 - 'd':0,
237 - 'media':['image','video'],
238 - 'doEdit':function( _this ){
239 - //do clock mouse scroll duration editor
240 - $j('#sub_cliplib_ic').html('<h3>Set Position</h3><h3>Set Zoom</h3><h3>Set Crop</h3><h3>Set Aspect</h3>');
241 - }
242 - },
243 - 'overlays':{
244 - 'd':0,
245 - 'media':['image','video'],
246 - 'doEdit':function( _this ){
247 - //do clock mouse scroll duration editor
248 - $j('#sub_cliplib_ic').html('<h3>Current Overlays:</h3>Add,Remove,Modify');
249 - }
250 - },
251 - 'audio':{
252 - 'd':0,
253 - 'media':['image','video', 'template'],
254 - 'doEdit':function( _this ){
255 - //do clock mouse scroll duration editor
256 - $j('#sub_cliplib_ic').html('<h3>Audio Volume:</h3>');
257 - }
258 - }
259 - },
260 - doEditTypesMenu:function(){
261 - var _this = this;
262 - //add in subMenus if set
263 - //check for submenu and add to item container
264 - var o='';
265 - o+= '<ul id="mv_submenu_clipedit" class="mv_submenu">';
266 - $j.each(this.edit_types, function(sInx, editType){
267 - //check if the given editType is valid for our given media type
268 - var include = false;
269 - for(var i =0; i < editType.media.length;i++){
270 - if( editType.media[i] == _this.media_type)
271 - include = true;
272 - }
273 - if(include){
274 - var sub_sel_class = (editType.d == 1)?'class="mv_sub_selected"':'';
275 - o+= '<li ' + sub_sel_class + ' id="mv_smi_' + sInx + '">' +
276 - getMsg('sc_' + sInx ) + '</li>';
277 - }
278 - });
279 - o+= '</ul>';
280 - //add sub menu container with menu html:
281 - o+= '<div id="sub_cliplib_ic" class="submenu_container"></div>';
282 - $j('#'+this.control_ct).html( o ) ;
283 - //set up bindings:
284 - for( var i in this.edit_types){
285 - $j('#mv_smi_'+ i).click( function(){
286 - _this.doDisplayEdit( $j(this).attr("id").replace('mv_smi_','') );
287 - });
288 - }
289 - },
290 - doDisplayEdit:function( edit_type ){
291 - if(!edit_type)
292 - for(var i in this.edit_types){
293 - if(this.edit_types[i].d == 1)
294 - edit_type = i;
295 - }
296 - js_log('doDisplayEdit: ' + edit_type );
297 - //remove from all
298 - $j('#mv_submenu_clipedit li').removeClass('mv_sub_selected');
299 - //add selected class:
300 - $j('#mv_smi_' + edit_type).addClass('mv_sub_selected');
301 -
302 - //do edit interface for that edit type:
303 - if( this.edit_types[ edit_type ].doEdit )
304 - this.edit_types[ edit_type ].doEdit( this );
305 - },
306 - setUpVideoCtrl:function(){
307 - js_log('setUpVideoCtrl:f');
308 - var this_seq = this;
309 - var eb = $j('#embed_vid').get(0);
310 - //turn on preview to avoid onDone actions
311 - eb.preview_mode = true;
312 - $j('#'+this.control_ct).html('<h3>Edit Video Tools:</h3>');
313 - if( eb.supportsURLTimeEncoding() ){
314 - $j('#'+this.control_ct).append(
315 - this_seq.getSetInOut({
316 - 'start_ntp' : eb.start_ntp,
317 - 'end_ntp' : eb.end_ntp
318 - })
319 - );
320 - this_seq.setInOutBindings();
321 - }
322 - $j('#'+this.control_ct).append( this.getInsertDesc() );
323 -
324 - $j('#'+this.control_ct).append( '<b>Metavid clip inserts not yet supported</b>' +
325 - '<a href="#" class="mv_cancel_img_edit" title="' + getMsg('mv_cancel_image_insert')+'">' + getMsg('mv_cancel_image_insert') + '</a> ');
326 - //$j('#'+this.control_ct).append( this.getInsertDesc() + this.getInsertAction() );
327 -
328 - this.applyInsertControlBindings();
329 - },
330 - setInOutBindings:function(){
331 - //setup bindings for adjust / preview:
332 - add_adjust_hooks( 'rsd' );
333 - $j('#mv_preview_clip').click(function(){
334 - $j('#embed_vid').get(0).stop();
335 - $j('#embed_vid').get(0).play();
336 - });
337 - },
338 - getSetInOut:function( setInt ){
339 - return '<strong>Set in-out points</strong>'+
340 - '<table border="0" style="background: transparent; width:94%;height:50px;">'+
341 - '<tr>' +
342 - '<td style="width:50px">'+
343 - '<span style="font-size: small;" id="track_time_start_rsd">' + setInt.start_ntp +'</span>'+
344 - '</td>' +
345 - '<td>' +
346 - '<div style="border: 1px solid black; width: 100%; height: 5px; background-color: #888;" '+
347 - 'id="container_track_rsd">'+
348 - '<div id="resize_rsd" class="ui-resizable ui-draggable">'+
349 - '<div class="ui-resizable-w ui-resizable-handle"'+
350 - ' id="handle1_rsd" unselectable="on"/>'+
351 -
352 - '<div class="ui-resizable-e ui-resizable-handle" '+
353 - ' id="handle2_rsd" unselectable="on"/>'+
354 -
355 - '<div class="ui-dragSpan" id="dragSpan_rsd" style="cursor: move;"/>'+
356 - '</div>'+
357 - '</div>'+
358 - '</td>' +
359 - '<td style="width:50px">'+
360 - '<span style="font-size: small;" id="track_time_end_rsd">'+ setInt.end_ntp +'</span>'+
361 - '</td>' +
362 - '</tr>' +
363 - '</table>'+
364 - '<span style="float: left;">'+
365 - '<label class="mv_css_form" for="mv_start_hr_rsd"><i>Start time:</i></label>'+
366 - '<input id="mv_start_hr_rsd" class="mv_adj_hr" name="mv_start_hr_rsd" value="' + setInt.start_ntp + '" maxlength="8" size="8"/>'+
367 - '</span>'+
368 - '<span style="float: left;">'+
369 - '<label for="mv_end_hr_rsd" class="mv_css_form"><i>End time:</i></label>'+
370 - '<input name="mv_end_hr_rsd" id="mv_end_hr_rsd" value="' + setInt.end_ntp + '" maxlength="8" size="8" class="mv_adj_hr"/>'+
371 - '</span>'+
372 - '<div style="clear: both;"/>'+
373 - '<input id="mv_preview_clip" type="button" value="Preview/Play In-out points">';
374 - },
375 - getInsertDesc:function(){
376 - return '<h3>Inline Description</h3><br>'+
377 - '<textarea style="width:300px;" id="mv_inline_img_desc" rows="4" cols="30"></textarea><br>';
378 - },
379 - getInsertAction:function(){
380 - return '<h3>Actions</h3>'+
381 - '<input type="button" class="mv_insert_image_page" value="' + getMsg('mv_insert_image_page') + '"> '+
382 - '<input type="button" style="font-weight:bold" class="mv_preview_insert" value="' + getMsg('mv_preview_insert')+ '"> '+
383 - '<a href="#" class="mv_cancel_img_edit" title="' + getMsg('mv_cancel_image_insert')+'">' + getMsg('mv_cancel_image_insert') + '</a> ';
384 - },
385 - applyEdit:function(){
386 - if(this.media_type == 'image'){
387 - this.applyCrop();
388 - }else if(this.media_type == 'video'){
389 - this.applyVideoAdj();
390 - }
391 - },
392 - applyInsertControlBindings:function(){
393 - var _this = this;
394 - $j('.mv_insert_image_page').click(function(){
395 - _this.applyEdit();
396 - //copy over the desc text to the resource object
397 - _this.rObj['inlineDesc']= $j('#mv_inline_img_desc').val();
398 - _this.p_rsdObj.insertResource( _this.rObj );
399 - });
400 - $j('.mv_preview_insert').click(function(){
401 - _this.applyEdit();
402 - //copy over the desc text to the resource object
403 - _this.rObj['inlineDesc']= $j('#mv_inline_img_desc').val();
404 - _this.p_rsdObj.previewResource( _this.rObj );
405 - });
406 - $j('.mv_cancel_img_edit').click( function(){
407 - $j('#' + _this.parent_ct).fadeOut("fast");
408 - });
409 - },
410 - setUpImageCtrl:function(){
411 - var _this = this;
412 - //by default apply Crop tool
413 - $j('#'+this.control_ct).html(
414 - '<h3>Edit tools</h3>' +
415 - '<div class="mv_edit_button mv_crop_button_base" id="mv_crop_button" alt="crop" title="'+getMsg('mv_crop')+'"/>'+
416 - '<a href="#" class="mv_crop_msg">' + getMsg('mv_crop') + '</a> '+
417 - '<span style="display:none" class="mv_crop_msg_load">' + getMsg('loading_txt') + '</span> '+
418 - '<a href="#" style="display:none" class="mv_apply_crop">' + getMsg('mv_apply_crop') + '</a> '+
419 - '<a href="#" style="display:none" class="mv_rest_crop">' + getMsg('mv_reset_crop') + '</a> '+
420 - '<br style="clear:both"><br>'+
421 - /*'<div class="mv_edit_button mv_scale_button_base" id="mv_scale_button" alt="crop" title="'+getMsg('mv_scale')+'"></div>'+
422 - '<a href="#" class="mv_scale_msg">' + getMsg('mv_scale') + '</a><br>'+
423 - '<a href="#" style="display:none" class="mv_apply_scale">' + getMsg('mv_apply_scale') + '</a> '+
424 - '<a href="#" style="display:none" class="mv_rest_scale">' + getMsg('mv_reset_scale') + '</a><br> '+
425 - */
426 - _this.getInsertDesc() +
427 - _this.getInsertAction()
428 - );
429 - //add bindings:
430 - $j('#mv_crop_button,.mv_crop_msg,.mv_apply_crop').click(function(){
431 - js_log('click:mv_crop_button: base width: ' + _this.rObj.width + ' bh: ' + _this.rObj.height);
432 - if($j('#mv_crop_button').hasClass('mv_crop_button_selected')){
433 - _this.applyCrop();
434 - }else{
435 - js_log('click:turn on');
436 - _this.enableCrop();
437 - }
438 - });
439 - $j('.mv_rest_crop').click(function(){
440 - $j('.mv_apply_crop,.mv_rest_crop').hide();
441 - $j('.mv_crop_msg').show();
442 - $j('#mv_crop_button').removeClass('mv_crop_button_selected').addClass('mv_crop_button_base').attr('title',getMsg('mv_crop'));
443 - _this.rObj.crop=null;
444 - $j('#' + _this.clip_disp_ct ).empty().html(
445 - '<img src="' + _this.rObj.url + '" id="rsd_edit_img">'
446 - );
447 - });
448 - this.applyInsertControlBindings();
449 - },
450 - applyVideoAdj:function(){
451 - //update video related keys
452 - this.rObj['start_time'] = $j('#mv_start_hr_rsd').val();
453 - this.rObj['end_time'] = $j('#mv_end_hr_rsd').val();
454 - //select the ogg stream
455 - if( this.rObj.pSobj.cp.stream_import_key && this.rObj.roe_url){
456 - var source = $j('#embed_vid').get(0).media_element.getSourceById( this.rObj.pSobj.cp.stream_import_key );
457 - this.rObj['src'] = source.getURI();
458 - js_log("g src_key: " + this.rObj.pSobj.cp.stream_import_key + ' src:' + this.rObj['src']) ;
459 - }
460 - //update the title:
461 - this.rObj['title'] = ' updated title';
462 - },
463 - applyCrop:function(){
464 - var _this = this;
465 - $j('.mv_apply_crop').hide();
466 - $j('.mv_crop_msg').show();
467 - $j('#mv_crop_button').removeClass('mv_crop_button_selected').addClass('mv_crop_button_base').attr('title',getMsg('mv_crop'));
468 - js_log('click:turn off');
469 - if(_this.rObj.crop){
470 - //empty out and display croped:
471 - $j('#'+_this.clip_disp_ct ).empty().html(
472 - '<div id="mv_cropcotainer" style="overflow:hidden;position:absolute;'+
473 - 'width:' + _this.rObj.crop.w + 'px;'+
474 - 'height:' + _this.rObj.crop.h + 'px;">'+
475 - '<div id="mv_crop_img" style="position:absolute;'+
476 - 'top:-' + _this.rObj.crop.y +'px;'+
477 - 'left:-' + _this.rObj.crop.x + 'px;">'+
478 - '<img src="' + _this.rObj.url + '">'+
479 - '</div>'+
480 - '</div>'
481 - );
482 - }
483 - },
484 - //right now enableCrop loads "just in time"
485 - //@@todo we really need an "auto loader" type system.
486 - enableCrop:function(){
487 - var _this = this;
488 - $j('.mv_crop_msg').hide();
489 - $j('.mv_crop_msg_load').show();
490 - var doEnableCrop = function(){
491 - $j('.mv_crop_msg_load').hide();
492 - $j('.mv_rest_crop,.mv_apply_crop').show();
493 - $j('#mv_crop_button').removeClass('mv_crop_button_base').addClass('mv_crop_button_selected').attr('title',getMsg('mv_crop_done'));
494 - $j('#' + _this.clip_disp_ct + ' img').Jcrop({
495 - onSelect: function(c){
496 - js_log('on select:' + c.x +','+ c.y+','+ c.x2+','+ c.y2+','+ c.w+','+ c.h);
497 - _this.rObj.crop = c;
498 - },
499 - onChange: function(c){
500 - }
501 - });
502 - }
503 - if(typeof $j.Jcrop == 'undefined'){
504 - loadExternalCss( mv_embed_path + 'jquery/plugins/Jcrop/css/jquery.Jcrop.css');
505 - //load the jcrop library if needed:
506 - mvJsLoader.doLoad({'$j.Jcrop':'jquery/plugins/Jcrop/js/jquery.Jcrop.js'},function(){
507 - doEnableCrop();
508 - });
509 - }else{
510 - doEnableCrop();
511 - }
512 -
513 - }
514 -}
515 -
516 -
517 -
518 -// mv_lock_vid_updates defined in mv_stream.js (we need to do some more refactoring )
519 -if(typeof mv_lock_vid_updates == 'undefined')
520 - mv_lock_vid_updates= false;
521 -
522 -function add_adjust_hooks(mvd_id){
523 - js_log('add_adjust_hooks: ' + mvd_id );
524 - //if options are unset populate functions:
525 - //add mouse over end time frame highlight
526 - $j('#mv_end_hr_'+mvd_id).hoverIntent({interval:200,over:function(){
527 - //js_log('pre style: ' + $j(this).css('border'));
528 - $j(this).css('border','solid red');
529 - do_video_time_update( $j('#mv_end_hr_'+mvd_id).val(), $j('#mv_end_hr_'+mvd_id).val() );
530 - },out:function(){
531 - $j(this).css('border','solid black thin');
532 - do_video_time_update($j('#mv_start_hr_'+mvd_id).val(), $j('#mv_end_hr_'+mvd_id).val() );
533 - }});
534 - //add onchange js hooks:
535 - $j('.mv_adj_hr').change(function(){
536 - //preserve track duration for nav and seq:
537 - //ie seems to crash so no interface updates for IE for the time being
538 - if(!$j.browser.msie){
539 - if(mvd_id=='nav'||mvd_id=='seq'){
540 - add_adjust_hooks(mvd_id);
541 - }else{
542 - add_adjust_hooks(mvd_id)
543 - }
544 - }
545 - //update the video time for onChange
546 - do_video_time_update($j('#mv_start_hr_'+mvd_id).val(), $j('#mv_end_hr_'+mvd_id).val() );
547 - });
548 - //read the ntp time from the fields
549 - var start_sec = ntp2seconds( $j('#mv_start_hr_'+mvd_id).val() );
550 - var end_sec = ntp2seconds( $j('#mv_end_hr_'+mvd_id).val() );
551 - js_log('start_sec:'+start_sec + ' end: ' + end_sec);
552 - if(start_sec > end_sec){
553 - js_log('start > end : ' + start_sec + ' > ' + end_sec);
554 - //update end time to start_time + 1 second
555 - end_sec = parseInt(start_sec+1);
556 - $j('#mv_end_hr_'+mvd_id).val(seconds2ntp(end_sec));
557 - }
558 -
559 - var duration = end_sec - start_sec;
560 - //set the track duration as 2 min or 2*duration (whatever is longer)
561 - var track_dur = (duration*2<120)?120:duration*2;
562 -
563 - //set the base offset
564 - if(start_sec==0){
565 - var base_offset = 0
566 - }else{
567 - //make sure we won't go into negative with a 1/4 track offset
568 - //alert('wtf:s:' + start_sec + '-' + (track_dur*.25) );
569 - var base_offset= start_sec-(track_dur*.25);
570 - //alert('wtf: '+ base_offset);
571 - if(base_offset < 0)
572 - base_offset=0;
573 - //js_log('set base offset: '+track_dur +'* .25 = '+ parseInt(base_offset) );
574 - }
575 - js_log('BASE OFFSET: '+ base_offset);
576 - //set the base offset / track_dur interface vars:
577 - $j('#track_time_start_'+mvd_id).html( seconds2ntp(base_offset) );
578 - $j('#track_time_end_'+mvd_id).html( seconds2ntp( base_offset+track_dur ));
579 -
580 - //set up start /end slider values:
581 - var slider_start = (start_sec - base_offset) / track_dur;
582 - var slider_end = (end_sec - base_offset) / track_dur;
583 - var slider_dur = slider_end -slider_start;
584 - //clear out the existing effect if present
585 - //if(mv_sliders[mvd_id])mv_sliders[mvd_id].dispose();
586 -
587 - //update the slider values (left right)
588 - track_width = $j('#container_track_'+mvd_id).width();
589 -
590 - js_log('start: '+ slider_start + ' =' + (slider_start*track_width) +
591 - ' se:'+ slider_end + ' =' + (slider_end*track_width) +
592 - ' width would be: :' + Math.round((slider_end*track_width)-(slider_start*track_width)));
593 -
594 - //if re-size width less than width of image bump it up:
595 - var resize_width = Math.round((slider_end*track_width)-(slider_start*track_width));
596 - if( resize_width < 17 ) resize_width=17;
597 -
598 - $j('#resize_'+mvd_id).css({
599 - left:Math.round(slider_start*track_width)+'px',
600 - width: resize_width+'px'
601 - });
602 - js_log("track width: " + $j('#container_track_'+mvd_id).width() +
603 - ' slider_width: ' + $j('#resize_'+mvd_id).width());
604 - //add an additional flag
605 - var cur_handle = '';
606 - $j('.ui-resizable-handle').mousedown( function(){
607 - js_log('hid: ' + this.id);
608 - cur_handle = this.id;
609 - });
610 - org_start = org_end ='';
611 - //jQuery slider:
612 - $j('#resize_'+mvd_id).resizable({
613 - minWidth: 10,
614 - maxWidth: $j('#resize_'+mvd_id).width(),
615 - minHeight: 20,
616 - maxHeight: 20,
617 - handles: {
618 - e: '.ui-resizable-e',
619 - w: '.ui-resizable-w'
620 - },
621 - start: function(e,ui) {
622 - mv_lock_vid_updates=true;
623 - org_start = $j('#mv_start_hr_'+mvd_id).val();
624 - org_end = $j('#mv_end_hr_'+mvd_id).val();
625 - //js_log("org maxWidth: " + ui.options.maxWidth);
626 - right_x = ( $j('#resize_'+mvd_id).position().left+
627 - $j('#resize_'+mvd_id).width()
628 - );
629 - /*js_log('left:' + $j('#resize_'+mvd_id).position().left + ' width: '+
630 - * $j('#resize_'+mvd_id).width() + ' right_x:'+ right_x);
631 - */
632 - if(cur_handle.indexOf('handle1')!=-1){
633 - ui.options.maxWidth= right_x;
634 - }else{
635 - ui.options.maxWidth= (
636 - $j('#container_track_'+mvd_id).width() -
637 - $j('#resize_'+mvd_id).position().left
638 - );
639 - }
640 - js_log("updated maxWidth: " + ui.options.maxWidth);
641 - //js_log('grabbed: ' + e.explicitOriginalTarget.id);
642 - //console.log('start ', ui);
643 - },
644 - stop: function(e,ui) {
645 - mv_lock_vid_updates=false;
646 - //console.log('stop ', ui);
647 - //return the non-adjusted to its original value:
648 - if(cur_handle.indexOf('handle1')!=-1){
649 - $j('#mv_end_hr_'+mvd_id).val(org_end);
650 - }else{
651 - $j('#mv_start_hr_'+mvd_id).val(org_start);
652 - }
653 - //update the clip
654 - do_video_time_update($j('#mv_start_hr_'+mvd_id).val(), $j('#mv_end_hr_'+mvd_id).val() );
655 - },
656 - resize: function(e,ui) {
657 - base_offset = ntp2seconds( $j('#track_time_start_'+mvd_id).html());
658 - mv_slider_update_stats(mvd_id);
659 - }
660 - });
661 - $j('#dragSpan_'+mvd_id).css('cursor','move');
662 - $j('#resize_'+mvd_id).draggable({
663 - axis:'x',
664 - containment:'parent',
665 - handle: "#dragSpan_"+mvd_id,
666 - drag:function(e, ui){
667 - mv_slider_update_stats(mvd_id, true);
668 - },
669 - stop:function(e,ui){
670 - do_video_time_update($j('#mv_start_hr_'+mvd_id).val(), $j('#mv_end_hr_'+mvd_id).val() );
671 - }
672 - });
673 - //store the necessary values in the slider obj
674 - //mv_sliders[mvd_id]['base_offset']=base_offset;
675 - //mv_sliders[mvd_id]['track_dur']=track_dur;
676 - function mv_slider_update_stats(mvd_id, drag){
677 - var update_start=update_end=false;
678 - //only update the side we are dragging:
679 - if(cur_handle.indexOf('handle1')!=-1){
680 - update_start=true;
681 - }else{
682 - update_end=true;
683 - }
684 - if(drag)update_end=update_start=true;
685 - if(update_end){
686 - var end_time = base_offset + (track_dur *(($j('#resize_'+mvd_id).position().left +
687 - $j('#resize_'+mvd_id).width()) /
688 - $j('#container_track_'+mvd_id).width()));
689 - if(end_time>(track_dur+base_offset))end_time=track_dur+base_offset;
690 - $j('#mv_end_hr_'+mvd_id).val( seconds2ntp(end_time) );
691 - }
692 - if(update_start)
693 - $j('#mv_start_hr_'+mvd_id).val( seconds2ntp(base_offset + (track_dur *($j('#resize_'+mvd_id).position().left /
694 - $j('#container_track_'+mvd_id).width()) ) ));
695 - }
696 -}
697 -function do_video_time_update(start_time, end_time, mvd_id) {
698 - js_log('do_video_time_update: ' +start_time + end_time);
699 - if(mv_lock_vid_updates==false){
700 - //update the vid title:
701 - $j('#mv_videoPlayerTime').html( start_time + ' to ' + end_time );
702 - var ebvid = $j('#embed_vid').get(0);
703 - if( ebvid ){
704 - if(ebvid.isPaused())
705 - ebvid.stop();
706 - ebvid.updateVideoTime(start_time, end_time);
707 - js_log('update thumb: '+ start_time);
708 - ebvid.updateThumbTimeNTP( start_time );
709 - }
710 - }
711 -}
\ No newline at end of file
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libSequencer/mv_sequencer.js
@@ -10,57 +10,57 @@
1111 *
1212 *
1313 * mv_sequencer.js
14 - * is a basic embeddable sequencer.
 14+ * is a basic embeddeble sequencer.
1515 * extends the playlist with drag/drop/sortable/add/remove functionality
1616 * editing of annotative content (mostly for wiki)
1717 * enables more dynamic layouts
1818 * exports back out to json or inline format
1919 */
20 -
21 -gMsg['menu_clipedit'] = 'Edit Selected Resource';
2220
 21+loadGM( {
 22+ 'menu_clipedit' : 'Edit Selected Resource',
 23+ 'menu_cliplib' : 'Add Resource',
 24+ 'menu_transition' : 'Transitions Effects',
 25+ 'menu_resource_overview' : 'Resource Overview',
 26+ 'menu_options' : 'Options',
2327
24 -gMsg['menu_cliplib'] = 'Add Resource';
25 -gMsg['menu_transition'] = 'Transitions Effects';
26 -gMsg['menu_resource_overview'] = 'Resource Overview';
27 -gMsg['menu_options'] = 'Options';
 28+ 'loading_timeline' : 'Loading TimeLine <blink>...</blink>',
 29+ 'loading_user_rights' : 'Loading user rights <blink>...</blink>',
 30+
 31+ 'no_edit_permissions' : 'You don\'t have permissions to save changes to this sequence',
 32+
 33+
 34+ 'edit_clip' : 'Edit Clip',
 35+ 'edit_save' : 'Save Changes',
 36+ 'edit_cancel' : 'Cancel Edit',
 37+ 'edit_cancel_confirm' : 'Are you sure you want to cancel your edit, changes will be lost',
 38+
 39+ 'zoom_in' : 'Zoom In',
 40+ 'zoom_out' : 'Zoom Out',
 41+ 'cut_clip' : 'Cut Clips',
 42+ 'expand_track' : 'Expand Track',
 43+ 'colapse_track' : 'Collapse Track',
 44+ 'play_clip' : 'Play From Playline Position',
 45+ 'pixle2sec' : 'pixles to seconds',
 46+ 'rmclip' : 'Remove Clip',
 47+ 'clip_in' : 'clip in',
 48+ 'clip_out' : 'clip out',
 49+
 50+ //menu items display helper:
 51+ 'mv_welcome_to_sequencer' : '<h3>Welcome to the sequencer demo</h3>'+
 52+ 'very <b>limited</b> functionality right now. Not much documentation yet either',
 53+
 54+ 'no_selected_resource' : '<h3>No Resource selected</h3> Select a Clip to enable resource editing',
 55+ 'error_edit_multiple' : '<h3>Multiple Resources Selected</h3> Select a single clip to edit it',
 56+
 57+ 'mv_editor_options' : 'Editor options',
 58+ 'mv_editor_mode' : 'Editor mode',
 59+ 'mv_simple_editor_desc' : 'simple editor (iMovie style)',
 60+ 'mv_advanced_editor_desc' : 'advanced editor (Final Cut style)',
 61+ 'mv_other_options' : 'Other Options',
 62+ 'mv_contextmenu_opt' : 'Enable Context Menus'
 63+});
2864
29 -gMsg['loading_timeline'] = 'Loading TimeLine <blink>...</blink>';
30 -gMsg['loading_user_rights'] = 'Loading user rights <blink>...</blink>';
31 -
32 -gMsg['no_edit_permissions'] = 'You don\'t have permissions to save changes to this sequence';
33 -
34 -
35 -gMsg['edit_clip'] = 'Edit Clip';
36 -gMsg['edit_save'] = 'Save Changes';
37 -gMsg['edit_cancel'] = 'Cancel Edit';
38 -gMsg['edit_cancel_confirm'] = 'Are you sure you want to cancel your edit, changes will be lost';
39 -
40 -gMsg['zoom_in'] = 'Zoom In';
41 -gMsg['zoom_out'] = 'Zoom Out';
42 -gMsg['cut_clip'] = 'Cut Clips';
43 -gMsg['expand_track'] = 'Expand Track';
44 -gMsg['colapse_track'] = 'Collapse Track';
45 -gMsg['play_clip'] = 'Play From Playline Position';
46 -gMsg['pixle2sec'] = 'pixles to seconds';
47 -gMsg['rmclip'] = 'Remove Clip';
48 -gMsg['clip_in'] = 'clip in';
49 -gMsg['clip_out'] = 'clip out';
50 -
51 -//menu items display helper:
52 -gMsg['mv_welcome_to_sequencer'] = '<h3>Welcome to the sequencer demo</h3>'+
53 -'very <b>limited</b> functionality right now. Not much documentation yet either';
54 -
55 -gMsg['no_selected_resource'] = '<h3>No Resource selected</h3> Select a Clip to enable resource editing';
56 -gMsg['error_edit_multiple'] = '<h3>Multiple Resources Selected</h3> Select a single clip to edit it';
57 -
58 -gMsg['mv_editor_options'] = 'Editor options';
59 -gMsg['mv_editor_mode'] = 'Editor mode';
60 -gMsg['mv_simple_editor_desc'] = 'simple editor (iMovie style)';
61 -gMsg['mv_advanced_editor_desc'] = 'advanced editor (Final Cut style)';
62 -gMsg['mv_other_options'] = 'Other Options';
63 -gMsg['mv_contextmenu_opt'] = 'Enable Context Menus';
64 -
6565 //used to set default values and validate the passed init object
6666 var sequencerDefaultValues = {
6767
@@ -124,7 +124,7 @@
125125 },
126126 'cliplib':{
127127 'd':0,
128 - 'html': getMsg('loading_txt'),
 128+ 'html': gM('loading_txt'),
129129 'js':function( this_seq ){
130130 //load the search interface with sequence tool targets
131131 mvJsLoader.doLoad({'remoteSearchDriver':'libAddMedia/mv_remote_media_search.js'}, function(){
@@ -139,22 +139,22 @@
140140 },
141141 'transition':{
142142 'd':0,
143 - 'html' : '<h3>' + getMsg('menu_transition') + '</h3>',
 143+ 'html' : '<h3>' + gM('menu_transition') + '</h3>',
144144 'js':function(this_seq){
145145 this_seq.renderTransitionsSet('transition_ic');
146146 }
147147 },
148148 'options':{
149149 'd':0,
150 - 'html' : '<h3>' + getMsg('menu_options') + '</h3>' +
151 - getMsg('mv_editor_mode') + '<br> ' +
 150+ 'html' : '<h3>' + gM('menu_options') + '</h3>' +
 151+ gM('mv_editor_mode') + '<br> ' +
152152 '<blockquote><input type="radio" value="simple_editor" name="opt_editor">' +
153 - getMsg('mv_simple_editor_desc') + ' </blockquote>' +
 153+ gM('mv_simple_editor_desc') + ' </blockquote>' +
154154 '<blockquote><input type="radio" value="advanced_editor" name="opt_editor">' +
155 - getMsg('mv_advanced_editor_desc') + ' </blockquote>'+
156 - getMsg('mv_other_options') + '<br>' +
 155+ gM('mv_advanced_editor_desc') + ' </blockquote>'+
 156+ gM('mv_other_options') + '<br>' +
157157 '<blockquote><input type="checkbox" value="contextmenu_opt" name="contextmenu_opt">' +
158 - getMsg('mv_contextmenu_opt') + ' </blockquote>',
 158+ gM('mv_contextmenu_opt') + ' </blockquote>',
159159 'js':function(this_seq){
160160 $j('#options_ic input[value=\'simple_editor\']').attr({
161161 'checked':(this_seq.timeline_mode=='storyboard')?true:false
@@ -213,11 +213,11 @@
214214 'left:0px;right:'+(this.video_width+10)+'px;top:0px;height:'+(this.video_height+28)+'px;border:solid thin black;"/>'+
215215 '<div id="'+this.timeline_id+'" style="position:absolute;' +
216216 'left:0px;right:0px;top:'+(this.video_height+10)+'px;bottom:25px;overflow:auto;">'+
217 - getMsg('loading_timeline')+ '</div>'+
 217+ gM('loading_timeline')+ '</div>'+
218218 '<div id="' + this.sequence_container_id + '_status" style="position:absolute;left:0px;width:300px;"></div>'+
219219 '<div id="' + this.sequence_container_id + '_save_cancel" style="position:absolute;'+
220220 'right:0px;bottom:0px;height:25px;overflow:hidden;">'+
221 - getMsg('loading_user_rights') +
 221+ gM('loading_user_rights') +
222222 '</div>'
223223 );
224224
@@ -254,9 +254,9 @@
255255 },
256256 updateSeqSaveButtons:function(){
257257 var cancel_button = '<a style="border:' +
258 - 'solid gray;font-size:1.2em;" onClick="window.confirm(\''+getMsg('edit_cancel_confirm')+'\')" '+
 258+ 'solid gray;font-size:1.2em;" onClick="window.confirm(\''+gM('edit_cancel_confirm')+'\')" '+
259259 'href="javascript:'+this.instance_name+'.closeModEditor()">'+
260 - getMsg('edit_cancel') + '</a> ';
 260+ gM('edit_cancel') + '</a> ';
261261 if( this.sequenceEditToken ){
262262 $j('#'+this.sequence_container_id+'_save_cancel').html( cancel_button +
263263 '<a style="border:solid gray;font-size:1.2em;" href="#" onClick="'+this.instance_name+'.getSeqOutputJSON()">'+
@@ -266,7 +266,7 @@
267267 'Preview XML Output (will be save shortly) ' +
268268 '</a>');
269269 }else{
270 - $j('#'+this.sequence_container_id+'_save_cancel').html( cancel_button + getMsg('no_edit_permissions') );
 270+ $j('#'+this.sequence_container_id+'_save_cancel').html( cancel_button + gM('no_edit_permissions') );
271271 }
272272 },
273273 //display a menu item (hide the rest)
@@ -332,18 +332,18 @@
333333 $j('#'+this.timeline_id).html(''+
334334 '<div id="'+this.timeline_id+'_left_cnt" class="mv_tl_left_cnt">'+
335335 '<div id="'+this.timeline_id+'_head_control" style="position:absolute;top:0px;left:0px;right:0px;height:30px;">' +
336 - '<a title="'+getMsg('play_clip')+'" href="javascript:'+this.instance_name+'.play_jt()">'+
 336+ '<a title="'+gM('play_clip')+'" href="javascript:'+this.instance_name+'.play_jt()">'+
337337 '<img style="width:16px;height:16px;border:0" src="' + mv_embed_path + 'images/control_play_blue.png">'+
338338 '</a>'+
339 - '<a title="'+getMsg('zoom_in')+'" href="javascript:'+this.instance_name+'.zoom_in()">'+
 339+ '<a title="'+gM('zoom_in')+'" href="javascript:'+this.instance_name+'.zoom_in()">'+
340340 '<img style="width:16px;height:16px;border:0" src="' + mv_embed_path + 'images/zoom_in.png">'+
341341 '</a>'+
342 - '<a title="'+getMsg('zoom_out')+'" href="javascript:'+this.instance_name+'.zoom_out()">'+
 342+ '<a title="'+gM('zoom_out')+'" href="javascript:'+this.instance_name+'.zoom_out()">'+
343343 '<img style="width:16px;height:16px;border:0" src="' + mv_embed_path + 'images/zoom_out.png">'+
344344 '</a>'+
345 - '<a title="'+getMsg('cut_clip')+'" href="javascript:'+this.instance_name+'.cut_mode()">'+
 345+ '<a title="'+gM('cut_clip')+'" href="javascript:'+this.instance_name+'.cut_mode()">'+
346346 '<img style="width:16px;height:16px;border:0" src="' + mv_embed_path + 'images/cut.png">'+
347 - '</a>'+
 347+ '</a>'+
348348 '</div>' +
349349 '</div>' +
350350 '<div id="'+this.timeline_id+'_tracks" class="mv_seq_tracks">' +
@@ -365,13 +365,13 @@
366366 var track_height=60;
367367 var exc_img = 'opened';
368368 var exc_action='close';
369 - var exc_msg = getMsg('colapse_track');
 369+ var exc_msg = gM('colapse_track');
370370 break;
371371 case 'text':
372372 var track_height=20;
373373 var exc_img = 'closed';
374374 var exc_action='open';
375 - var exc_msg = getMsg('expand_track');
 375+ var exc_msg = gM('expand_track');
376376 break;
377377 }
378378 //add track name:
@@ -505,15 +505,15 @@
506506 $j.each(this.menu_items, function(inx, menu_item){
507507 var disp_style = (menu_item.d)?'inline':'none';
508508 var sel_class = (menu_item.d)?'class="mv_selected_item"':'';
509 - menu_html+='<li '+sel_class+' id="mv_menu_item_'+inx+'">' + getMsg('menu_' + inx ) +'</li>';
 509+ menu_html+='<li '+sel_class+' id="mv_menu_item_'+inx+'">' + gM('menu_' + inx ) +'</li>';
510510 item_containers += '<div class="seq_control_container" id="' + inx +
511511 '_ic" style="display:' + disp_style +';">'
512 - item_containers += (menu_item.html) ? menu_item.html : '<h3>' + getMsg('menu_'+inx) + '</h3>';
 512+ item_containers += (menu_item.html) ? menu_item.html : '<h3>' + gM('menu_'+inx) + '</h3>';
513513 item_containers +='</div>';
514514 });
515515 menu_html+='</ul>';
516516
517 - item_containers+='<div class="seq_control_container" id="welcome_ic">' + getMsg('mv_welcome_to_sequencer') + '</div>';
 517+ item_containers+='<div class="seq_control_container" id="welcome_ic">' + gM('mv_welcome_to_sequencer') + '</div>';
518518
519519 $j('#'+this.sequence_tools_id).html( menu_html + item_containers );
520520 //add binding for menu
@@ -654,10 +654,10 @@
655655 });
656656 }else if( num_sel === 0){
657657 //no clip selected warning:
658 - $j('#clipedit_ic').html( getMsg('no_selected_resource') );
 658+ $j('#clipedit_ic').html( gM('no_selected_resource') );
659659 }else if( num_sel > 1){
660660 //multiple clip selected warning:
661 - $j('#clipedit_ic').html( getMsg('error_edit_multiple') );
 661+ $j('#clipedit_ic').html( gM('error_edit_multiple') );
662662 }
663663 }
664664 },
@@ -670,7 +670,7 @@
671671
672672 mv_get_loading_img( '#clipedit_ic' );
673673 //load the clipEdit library if not already loaded:
674 - mvJsLoader.doLoad( {'mvClipEdit' : 'libSequencer/mv_clipedit.js' }, function(){
 674+ mvJsLoader.doLoad( {'mvClipEdit' : 'libClipEdit/mv_clipedit.js' }, function(){
675675 //setup the cliploader
676676 this_seq.myClipEditor = new mvClipEdit({
677677 'rObj' : cObj,
@@ -958,9 +958,9 @@
959959 '" class="mv_time_clip_text mv_clip_drag">'+clip.title;
960960 }
961961 //add in per clip controls
962 - track_html+='<div title="'+getMsg('clip_in')+' '+clip.embed.start_ntp+'" class="ui-resizable-w ui-resizable-handle" style="width: 16px; height: 16px; left: 0px; top: 2px;background:url(\''+mv_embed_path+'images/application_side_contract.png\');" ></div>'+"\n";
963 - track_html+='<div title="'+getMsg('clip_out')+' '+clip.embed.end_ntp+'" class="ui-resizable-e ui-resizable-handle" style="width: 16px; height: 16px; right: 0px; top: 2px;background:url(\''+mv_embed_path+'images/application_side_expand.png\');" ></div>'+"\n";
964 - track_html+='<div title="'+getMsg('rmclip')+'" onClick="'+this.instance_name + '.removeClips(new Array([' + track_id + ',' + j + ']))" style="position:absolute;cursor:pointer;width: 16px; height: 16px; left: 0px; bottom:2px;background:url(\''+mv_embed_path+'images/delete.png\');"></div>'+"\n";
 962+ track_html+='<div title="'+gM('clip_in')+' '+clip.embed.start_ntp+'" class="ui-resizable-w ui-resizable-handle" style="width: 16px; height: 16px; left: 0px; top: 2px;background:url(\''+mv_embed_path+'images/application_side_contract.png\');" ></div>'+"\n";
 963+ track_html+='<div title="'+gM('clip_out')+' '+clip.embed.end_ntp+'" class="ui-resizable-e ui-resizable-handle" style="width: 16px; height: 16px; right: 0px; top: 2px;background:url(\''+mv_embed_path+'images/application_side_expand.png\');" ></div>'+"\n";
 964+ track_html+='<div title="'+gM('rmclip')+'" onClick="'+this.instance_name + '.removeClips(new Array([' + track_id + ',' + j + ']))" style="position:absolute;cursor:pointer;width: 16px; height: 16px; left: 0px; bottom:2px;background:url(\''+mv_embed_path+'images/delete.png\');"></div>'+"\n";
965965 track_html+='<span style="display:none;" class="mv_clip_stats"></span>';
966966
967967 track_html+='</span>';
@@ -980,16 +980,24 @@
981981 $j(this).removeClass("clip_edit_base").addClass("clip_edit_over");
982982 },function(){
983983 $j(this).removeClass("clip_edit_over").addClass("clip_edit_base");
984 - }).click(function(){
 984+ }).click(function(){
 985+ //deselect everything else:
 986+ $j('.mv_selected_clip').each(function(inx, selected_clip){
 987+ this_seq.deselectClip( this );
 988+ });
 989+ var sClipObj = this_seq.getClipFromSeqID( $j(this).parent().attr('id') );
 990+ this_seq.plObj.updateCurrentClip( sClipObj );
985991 //get the clip (siblings with mv_clip_thumb class)
986992 var cur_clip_elm = $j(this).siblings('.mv_clip_thumb');
987993 //select the clip (add mv_selected_clip if not already selected)
988994 if( ! $j( cur_clip_elm ).hasClass("mv_selected_clip") ){
989995 $j( cur_clip_elm ).addClass('mv_selected_clip');
990996 $j('#' + $j( cur_clip_elm ).parent().attr("id") + '_adj').fadeIn("fast");
991 - }
992 - //invoke the edit resource selected resource tab:
993 - this_seq.doEditSelectedClip();
 997+ }
 998+ //display the edit tab:
 999+ this_seq.disp( 'clipedit' );
 1000+ //display edit dialog:
 1001+ this_seq.doEditClip( sClipObj );
9941002 });
9951003
9961004 //apply onClick edit controls:
@@ -1002,8 +1010,7 @@
10031011 $j('.mv_selected_clip').each(function(inx, selected_clip){
10041012 if( $j(this).parent().attr('id') != $j(cur_clip_click).parent().attr('id')
10051013 || ( $j('.mv_selected_clip').length > 1 ) ){
1006 - $j(this).removeClass("mv_selected_clip");
1007 - $j('#' + $j(this).parent().attr("id") + '_adj').fadeOut("fast");
 1014+ this_seq.deselectClip( this );
10081015 }
10091016 });
10101017 }
@@ -1178,6 +1185,10 @@
11791186 //debugger;
11801187 }
11811188 },
 1189+ deselectClip:function( clipElm ){
 1190+ $j(clipElm).removeClass("mv_selected_clip");
 1191+ $j('#' + $j(clipElm).parent().attr("id") + '_adj').fadeOut("fast");
 1192+ },
11821193 getClipFromSeqID:function( clip_seq_id ){
11831194 js_log('get id from: ' + clip_seq_id);
11841195 var ct = clip_seq_id.replace('track_','').replace('clip_','').split('_');
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libClipEdit/mv_clipedit.js
@@ -0,0 +1,712 @@
 2+/*
 3+ hanndles clip edit controls
 4+ 'inoutpoints':0, //should let you set the in and out points of clip
 5+ 'panzoom':0, //should allow setting keyframes and tweening modes
 6+ 'overlays':0, //should allow setting "locked to clip" overlay tracks
 7+ 'audio':0 //should allow controlling the audio volume (with keyframes)
 8+*/
 9+//set gMsg object:
 10+loadGM( {
 11+ 'mv_crop':'Crop Image',
 12+ 'mv_apply_crop':'Apply Crop to Image',
 13+ 'mv_reset_crop':'Rest Crop',
 14+ 'mv_insert_image_page':'Insert Into page',
 15+ 'mv_preview_insert':'Preview Insert',
 16+ 'mv_cancel_image_insert':'Cancel Image Insert',
 17+
 18+ 'sc_fileopts':'Clip Detail Edit',
 19+ 'sc_inoutpoints':'Set In-Out points',
 20+ 'sc_panzoom':'Pan Zoom Crop',
 21+ 'sc_overlays':'Overlays',
 22+ 'sc_audio':'Audio Control',
 23+ 'sc_duration':'Duration',
 24+
 25+ 'mv_template_properties':'Template Properties',
 26+ 'mv_custom_title':'Custom Title',
 27+ 'mv_edit_properties':'Edit Properties',
 28+ 'mv_other_properties':'Other Properties',
 29+ 'mv_resource_page':'Resource Page'
 30+});
 31+
 32+var default_clipedit_values = {
 33+ 'rObj': null, // the resource object
 34+ 'clip_disp_ct':null,//target clip disp
 35+ 'control_ct':null, //control container
 36+ 'media_type': null, //media type
 37+ 'parent_ct': null, //parent container
 38+
 39+ 'p_rsdObj': null, //parent remote search object
 40+ 'p_seqObj': null, //parent sequence Object
 41+
 42+ 'edit_action': null, //the requested edit action
 43+ 'profile': 'inpage' //the given profile either "inpage" or "sequence"
 44+ //timeline invokes the timeline editor (letting you set keyframes)
 45+}
 46+var mvClipEdit = function(initObj) {
 47+ return this.init(initObj);
 48+};
 49+mvClipEdit.prototype = {
 50+
 51+ selTool:null, //selected tool
 52+ crop: null, //the crop values
 53+ base_img_src:null,
 54+
 55+ init:function( initObj){
 56+ //init object:
 57+ for(var i in default_clipedit_values){
 58+ if( initObj[i] ){
 59+ this[i] = initObj[i];
 60+ }
 61+ }
 62+
 63+ //if media type was not supplied detect for resoure if possible:
 64+ //@@todo more advanced detection.
 65+ if(!this.media_type){
 66+ if( this.rObj.type.indexOf("image/") === 0){
 67+ this.media_type = 'image';
 68+ }else if( this.rObj.type.indexOf("video/") === 0){
 69+ this.media_type = 'video';
 70+ }else if( this.rObj.type.indexOf("text/") === 0){
 71+ this.media_type = 'template';
 72+ }
 73+ }
 74+
 75+ //display control:
 76+ if(this.profile == 'sequence'){
 77+ this.doEditTypesMenu();
 78+ this.doDisplayEdit();
 79+ }else{
 80+ //check the media_type:
 81+ js_log('mvClipEdit:: media type:' + this.media_type + ' base width: ' + this.rObj.width + ' bh: ' + this.rObj.height);
 82+ //could seperate out into media Types objects for now just call method
 83+ if(this.media_type == 'image'){
 84+ this.setUpImageCtrl();
 85+ }else if(this.media_type=='video'){
 86+ this.setUpVideoCtrl();
 87+ }
 88+ }
 89+ },
 90+
 91+ //master edit types object:
 92+ //maybe we should refactor these into their own classes
 93+ //more refactor each media type should be its own class inheriting the shared baseEditType object
 94+ edit_types:{
 95+ 'fileopts':{
 96+ 'd':1,
 97+ 'media':['image','video','template'],
 98+ 'doEdit':function( _this ){
 99+ var doEditHtml = function(){
 100+ //add html for rObj resource:
 101+ var o= '<table>' +
 102+ '<tr>' +
 103+ '<td colspan="2"><b>'+gM('mv_edit_properties')+'</b></td>'+
 104+ '</tr>'+
 105+ '<tr>'+
 106+ '<td>' +
 107+ gM('mv_custom_title') +
 108+ '</td>'+
 109+ '<td><input type="text" size="15" maxwidth="255" value="';
 110+ if(_this.rObj.title != null)
 111+ o+=_this.rObj.title;
 112+ o+='">'+
 113+ '</td>'+
 114+ '</tr>';
 115+ if( _this.rObj.tVars){
 116+ var existing_p = _this.rObj.params;
 117+ var testing_a = _this.rObj.tVars;
 118+ //debugger;
 119+ o+= '<tr>'+
 120+ '<td colspan="2"><b>'+gM('mv_template_properties')+'</b></td>'+
 121+ '</tr>';
 122+ for(var i =0; i < _this.rObj.tVars.length ; i++){
 123+ o+='<tr>'+
 124+ '<td>' +
 125+ _this.rObj.tVars[i] +
 126+ '</td>' +
 127+ '<td><input type="text" size="15" maxwidth="255" value="';
 128+ if(_this.rObj.params[ _this.rObj.tVars[i] ]){
 129+ o+= _this.rObj.params[ _this.rObj.tVars[i] ];
 130+ }
 131+ o+='">'+
 132+ '</td>'+
 133+ '</tr>';
 134+ }
 135+ }
 136+ o+= '<tr>'+
 137+ '<td colspan="2"><b>'+gM('mv_other_properties')+'</b></td>'+
 138+ '</tr>'+
 139+ '<tr>'+
 140+ '<td>' +
 141+ gM('mv_resource_page') +
 142+ '</td>' +
 143+ '<td><a href="' + wgArticlePath.replace(/\$1/, _this.rObj.uri ) +
 144+ ' target="new">'+
 145+ _this.rObj.uri + '</a>'+
 146+ '</td>'+
 147+ '</tr>';
 148+ o+='</table>';
 149+
 150+ $j('#sub_cliplib_ic').html ( o );
 151+ //add update bindings
 152+
 153+ //update doFocusBindings
 154+ if( _this.p_seqObj )
 155+ _this.p_seqObj.doFocusBindings();
 156+ }
 157+ //if media type is template we have to query to get its URI to get its paramaters
 158+ if(_this.media_type == 'template' && !_this.rObj.tVars){
 159+ mv_set_loading('#sub_cliplib_ic');
 160+ var reqObj ={ 'action':'query',
 161+ 'prop':'revisions',
 162+ 'titles': _this.rObj.uri,
 163+ 'rvprop':'content'
 164+ };
 165+ //get the interface uri from the plObject
 166+ var api_url = _this.p_seqObj.plObj.interface_url.replace(/index\.php/, 'api.php');
 167+ //first check
 168+ do_api_req( reqObj, api_url,function(data){
 169+ if(typeof data.query.pages == 'undefined')
 170+ return doEditHtml();
 171+ for(var i in data.query.pages){
 172+ var page = data.query.pages[i];
 173+ var template_rev = page['revisions'][0]['*'];
 174+ }
 175+
 176+ //do a regular ex to get the ~likely~ template values
 177+ //(ofcourse this sucks)
 178+ //but maybe this will make its way into the api sometime soon to support wysiwyg type editors
 179+ //idealy it would expose a good deal of info about the template params
 180+ js_log('matching against: ' + template_rev);
 181+ var tempVars = template_rev.match(/\{\{\{([^\}]*)\}\}\}/gi);
 182+ //clean up results:
 183+ _this.rObj.tVars = new Array();
 184+ for(var i=0; i < tempVars.length; i++){
 185+ var tvar = tempVars[i].replace('{{{','').replace('}}}','');
 186+ //strip anything after a |
 187+ if(tvar.indexOf('|') != -1){
 188+ tvar = tvar.substr(0, tvar.indexOf('|'));
 189+ }
 190+ //check for duplicates:
 191+ var do_add=true;
 192+ for(var j=0; j < _this.rObj.tVars.length; j++){
 193+ js_log('checking: ' + _this.rObj.tVars[j] + ' against:' + tvar);
 194+ if( _this.rObj.tVars[j] == tvar)
 195+ do_add=false;
 196+ }
 197+ //add the template vars to the output obj
 198+ if(do_add)
 199+ _this.rObj.tVars.push( tvar );
 200+ }
 201+ doEditHtml();
 202+ });
 203+ }else{
 204+ doEditHtml();
 205+ }
 206+
 207+
 208+ }
 209+ },
 210+ 'duration':{
 211+ d:0,
 212+ 'media':['image','template'],
 213+ 'doEdit':function( _this ){
 214+ //do clock mouse scroll duration editor
 215+ $j('#sub_cliplib_ic').html('cur dur: ' + _this.rObj.dur );
 216+ }
 217+ },
 218+ 'inoutpoints':{
 219+ 'd':0,
 220+ 'media':['video'],
 221+ 'doEdit':function( _this ){
 222+ var cat = _this.rObj
 223+ //debugger;
 224+ //do clock mouse scroll duration editor
 225+ var end_ntp = ( _this.rObj.embed.end_ntp) ? _this.rObj.embed.end_ntp : _this.rObj.embed.getDuration();
 226+ if(!end_ntp)
 227+ end_ntp = seconds2ntp( _this.rObj.dur );
 228+ $j('#sub_cliplib_ic').html(
 229+ _this.getSetInOut({
 230+ 'start_ntp' : _this.rObj.embed.start_ntp,
 231+ 'end_ntp' : end_ntp
 232+ })
 233+ );
 234+ _this.setInOutBindings();
 235+ }
 236+ },
 237+ 'panzoom':{
 238+ 'd':0,
 239+ 'media':['image','video'],
 240+ 'doEdit':function( _this ){
 241+ //do clock mouse scroll duration editor
 242+ $j('#sub_cliplib_ic').html('<h3>Set Position</h3><h3>Set Zoom</h3><h3>Set Crop</h3><h3>Set Aspect</h3>');
 243+ }
 244+ },
 245+ 'overlays':{
 246+ 'd':0,
 247+ 'media':['image','video'],
 248+ 'doEdit':function( _this ){
 249+ //do clock mouse scroll duration editor
 250+ $j('#sub_cliplib_ic').html('<h3>Current Overlays:</h3>Add,Remove,Modify');
 251+ }
 252+ },
 253+ 'audio':{
 254+ 'd':0,
 255+ 'media':['image','video', 'template'],
 256+ 'doEdit':function( _this ){
 257+ //do clock mouse scroll duration editor
 258+ $j('#sub_cliplib_ic').html('<h3>Audio Volume:</h3>');
 259+ }
 260+ }
 261+ },
 262+ doEditTypesMenu:function(){
 263+ var _this = this;
 264+ //add in subMenus if set
 265+ //check for submenu and add to item container
 266+ var o='';
 267+ o+= '<ul id="mv_submenu_clipedit" class="mv_submenu">';
 268+ $j.each(this.edit_types, function(sInx, editType){
 269+ //check if the given editType is valid for our given media type
 270+ var include = false;
 271+ for(var i =0; i < editType.media.length;i++){
 272+ if( editType.media[i] == _this.media_type)
 273+ include = true;
 274+ }
 275+ if(include){
 276+ var sub_sel_class = (editType.d == 1)?'class="mv_sub_selected"':'';
 277+ o+= '<li ' + sub_sel_class + ' id="mv_smi_' + sInx + '">' +
 278+ gM('sc_' + sInx ) + '</li>';
 279+ }
 280+ });
 281+ o+= '</ul>';
 282+ //add sub menu container with menu html:
 283+ o+= '<div id="sub_cliplib_ic" class="submenu_container"></div>';
 284+ $j('#'+this.control_ct).html( o ) ;
 285+ //set up bindings:
 286+ for( var i in this.edit_types){
 287+ $j('#mv_smi_'+ i).click( function(){
 288+ _this.doDisplayEdit( $j(this).attr("id").replace('mv_smi_','') );
 289+ });
 290+ }
 291+ },
 292+ doDisplayEdit:function( edit_type ){
 293+ if(!edit_type)
 294+ for(var i in this.edit_types){
 295+ if(this.edit_types[i].d == 1)
 296+ edit_type = i;
 297+ }
 298+ js_log('doDisplayEdit: ' + edit_type );
 299+ //remove from all
 300+ $j('#mv_submenu_clipedit li').removeClass('mv_sub_selected');
 301+ //add selected class:
 302+ $j('#mv_smi_' + edit_type).addClass('mv_sub_selected');
 303+
 304+ //do edit interface for that edit type:
 305+ if( this.edit_types[ edit_type ].doEdit )
 306+ this.edit_types[ edit_type ].doEdit( this );
 307+ },
 308+ setUpVideoCtrl:function(){
 309+ js_log('setUpVideoCtrl:f');
 310+ var this_seq = this;
 311+ var eb = $j('#embed_vid').get(0);
 312+ //turn on preview to avoid onDone actions
 313+ eb.preview_mode = true;
 314+ $j('#'+this.control_ct).html('<h3>Edit Video Tools:</h3>');
 315+ if( eb.supportsURLTimeEncoding() ){
 316+ $j('#'+this.control_ct).append(
 317+ this_seq.getSetInOut({
 318+ 'start_ntp' : eb.start_ntp,
 319+ 'end_ntp' : eb.end_ntp
 320+ })
 321+ );
 322+ this_seq.setInOutBindings();
 323+ }
 324+ $j('#'+this.control_ct).append( this.getInsertDesc() );
 325+
 326+ $j('#'+this.control_ct).append( '<b>Metavid clip inserts not yet supported</b>' +
 327+ '<a href="#" class="mv_cancel_img_edit" title="' + gM('mv_cancel_image_insert')+'">' + gM('mv_cancel_image_insert') + '</a> ');
 328+ //$j('#'+this.control_ct).append( this.getInsertDesc() + this.getInsertAction() );
 329+
 330+ this.applyInsertControlBindings();
 331+ },
 332+ setInOutBindings:function(){
 333+ //setup bindings for adjust / preview:
 334+ add_adjust_hooks( 'rsd' );
 335+ $j('#mv_preview_clip').click(function(){
 336+ $j('#embed_vid').get(0).stop();
 337+ $j('#embed_vid').get(0).play();
 338+ });
 339+ },
 340+ getSetInOut:function( setInt ){
 341+ return '<strong>Set in-out points</strong>'+
 342+ '<table border="0" style="background: transparent; width:94%;height:50px;">'+
 343+ '<tr>' +
 344+ '<td style="width:50px">'+
 345+ '<span style="font-size: small;" id="track_time_start_rsd">' + setInt.start_ntp +'</span>'+
 346+ '</td>' +
 347+ '<td>' +
 348+ '<div style="border: 1px solid black; width: 100%; height: 5px; background-color: #888;" '+
 349+ 'id="container_track_rsd">'+
 350+ '<div id="resize_rsd" class="ui-resizable ui-draggable">'+
 351+ '<div class="ui-resizable-w ui-resizable-handle"'+
 352+ ' id="handle1_rsd" unselectable="on"/>'+
 353+
 354+ '<div class="ui-resizable-e ui-resizable-handle" '+
 355+ ' id="handle2_rsd" unselectable="on"/>'+
 356+
 357+ '<div class="ui-dragSpan" id="dragSpan_rsd" style="cursor: move;"/>'+
 358+ '</div>'+
 359+ '</div>'+
 360+ '</td>' +
 361+ '<td style="width:50px">'+
 362+ '<span style="font-size: small;" id="track_time_end_rsd">'+ setInt.end_ntp +'</span>'+
 363+ '</td>' +
 364+ '</tr>' +
 365+ '</table>'+
 366+ '<span style="float: left;">'+
 367+ '<label class="mv_css_form" for="mv_start_hr_rsd"><i>Start time:</i></label>'+
 368+ '<input id="mv_start_hr_rsd" class="mv_adj_hr" name="mv_start_hr_rsd" value="' + setInt.start_ntp + '" maxlength="8" size="8"/>'+
 369+ '</span>'+
 370+ '<span style="float: left;">'+
 371+ '<label for="mv_end_hr_rsd" class="mv_css_form"><i>End time:</i></label>'+
 372+ '<input name="mv_end_hr_rsd" id="mv_end_hr_rsd" value="' + setInt.end_ntp + '" maxlength="8" size="8" class="mv_adj_hr"/>'+
 373+ '</span>'+
 374+ '<div style="clear: both;"/>'+
 375+ '<input id="mv_preview_clip" type="button" value="Preview/Play In-out points">';
 376+ },
 377+ getInsertDesc:function(){
 378+ return '<h3>Inline Description</h3><br>'+
 379+ '<textarea style="width:300px;" id="mv_inline_img_desc" rows="4" cols="30"></textarea><br>';
 380+ },
 381+ getInsertAction:function(){
 382+ return '<h3>Actions</h3>'+
 383+ '<input type="button" class="mv_insert_image_page" value="' + gM('mv_insert_image_page') + '"> '+
 384+ '<input type="button" style="font-weight:bold" class="mv_preview_insert" value="' + gM('mv_preview_insert')+ '"> '+
 385+ '<a href="#" class="mv_cancel_img_edit" title="' + gM('mv_cancel_image_insert')+'">' + gM('mv_cancel_image_insert') + '</a> ';
 386+ },
 387+ applyEdit:function(){
 388+ if(this.media_type == 'image'){
 389+ this.applyCrop();
 390+ }else if(this.media_type == 'video'){
 391+ this.applyVideoAdj();
 392+ }
 393+ },
 394+ applyInsertControlBindings:function(){
 395+ var _this = this;
 396+ $j('.mv_insert_image_page').click(function(){
 397+ _this.applyEdit();
 398+ //copy over the desc text to the resource object
 399+ _this.rObj['inlineDesc']= $j('#mv_inline_img_desc').val();
 400+ _this.p_rsdObj.insertResource( _this.rObj );
 401+ });
 402+ $j('.mv_preview_insert').click(function(){
 403+ _this.applyEdit();
 404+ //copy over the desc text to the resource object
 405+ _this.rObj['inlineDesc']= $j('#mv_inline_img_desc').val();
 406+ _this.p_rsdObj.previewResource( _this.rObj );
 407+ });
 408+ $j('.mv_cancel_img_edit').click( function(){
 409+ $j('#' + _this.parent_ct).fadeOut("fast");
 410+ });
 411+ },
 412+ setUpImageCtrl:function(){
 413+ var _this = this;
 414+ //by default apply Crop tool
 415+ $j('#'+this.control_ct).html(
 416+ '<h3>Edit tools</h3>' +
 417+ '<div class="mv_edit_button mv_crop_button_base" id="mv_crop_button" alt="crop" title="'+gM('mv_crop')+'"/>'+
 418+ '<a href="#" class="mv_crop_msg">' + gM('mv_crop') + '</a> '+
 419+ '<span style="display:none" class="mv_crop_msg_load">' + gM('loading_txt') + '</span> '+
 420+ '<a href="#" style="display:none" class="mv_apply_crop">' + gM('mv_apply_crop') + '</a> '+
 421+ '<a href="#" style="display:none" class="mv_rest_crop">' + gM('mv_reset_crop') + '</a> '+
 422+ '<br style="clear:both"><br>'+
 423+ /*'<div class="mv_edit_button mv_scale_button_base" id="mv_scale_button" alt="crop" title="'+gM('mv_scale')+'"></div>'+
 424+ '<a href="#" class="mv_scale_msg">' + gM('mv_scale') + '</a><br>'+
 425+ '<a href="#" style="display:none" class="mv_apply_scale">' + gM('mv_apply_scale') + '</a> '+
 426+ '<a href="#" style="display:none" class="mv_rest_scale">' + gM('mv_reset_scale') + '</a><br> '+
 427+ */
 428+ _this.getInsertDesc() +
 429+ _this.getInsertAction()
 430+ );
 431+ //add bindings:
 432+ $j('#mv_crop_button,.mv_crop_msg,.mv_apply_crop').click(function(){
 433+ js_log('click:mv_crop_button: base width: ' + _this.rObj.width + ' bh: ' + _this.rObj.height);
 434+ if($j('#mv_crop_button').hasClass('mv_crop_button_selected')){
 435+ _this.applyCrop();
 436+ }else{
 437+ js_log('click:turn on');
 438+ _this.enableCrop();
 439+ }
 440+ });
 441+ $j('.mv_rest_crop').click(function(){
 442+ $j('.mv_apply_crop,.mv_rest_crop').hide();
 443+ $j('.mv_crop_msg').show();
 444+ $j('#mv_crop_button').removeClass('mv_crop_button_selected').addClass('mv_crop_button_base').attr('title',gM('mv_crop'));
 445+ _this.rObj.crop=null;
 446+ $j('#' + _this.clip_disp_ct ).empty().html(
 447+ '<img src="' + _this.rObj.url + '" id="rsd_edit_img">'
 448+ );
 449+ });
 450+ this.applyInsertControlBindings();
 451+ },
 452+ applyVideoAdj:function(){
 453+ //update video related keys
 454+ this.rObj['start_time'] = $j('#mv_start_hr_rsd').val();
 455+ this.rObj['end_time'] = $j('#mv_end_hr_rsd').val();
 456+ //select the ogg stream
 457+ if( this.rObj.pSobj.cp.stream_import_key && this.rObj.roe_url){
 458+ var source = $j('#embed_vid').get(0).media_element.getSourceById( this.rObj.pSobj.cp.stream_import_key );
 459+ this.rObj['src'] = source.getURI();
 460+ js_log("g src_key: " + this.rObj.pSobj.cp.stream_import_key + ' src:' + this.rObj['src']) ;
 461+ }
 462+ //update the title:
 463+ this.rObj['title'] = ' updated title';
 464+ },
 465+ applyCrop:function(){
 466+ var _this = this;
 467+ $j('.mv_apply_crop').hide();
 468+ $j('.mv_crop_msg').show();
 469+ $j('#mv_crop_button').removeClass('mv_crop_button_selected').addClass('mv_crop_button_base').attr('title',gM('mv_crop'));
 470+ js_log('click:turn off');
 471+ if(_this.rObj.crop){
 472+ //empty out and display croped:
 473+ $j('#'+_this.clip_disp_ct ).empty().html(
 474+ '<div id="mv_cropcotainer" style="overflow:hidden;position:absolute;'+
 475+ 'width:' + _this.rObj.crop.w + 'px;'+
 476+ 'height:' + _this.rObj.crop.h + 'px;">'+
 477+ '<div id="mv_crop_img" style="position:absolute;'+
 478+ 'top:-' + _this.rObj.crop.y +'px;'+
 479+ 'left:-' + _this.rObj.crop.x + 'px;">'+
 480+ '<img src="' + _this.rObj.url + '">'+
 481+ '</div>'+
 482+ '</div>'
 483+ );
 484+ }
 485+ },
 486+ //right now enableCrop loads "just in time"
 487+ //@@todo we really need an "auto loader" type system.
 488+ enableCrop:function(){
 489+ var _this = this;
 490+ $j('.mv_crop_msg').hide();
 491+ $j('.mv_crop_msg_load').show();
 492+ var doEnableCrop = function(){
 493+ $j('.mv_crop_msg_load').hide();
 494+ $j('.mv_rest_crop,.mv_apply_crop').show();
 495+ $j('#mv_crop_button').removeClass('mv_crop_button_base').addClass('mv_crop_button_selected').attr('title',gM('mv_crop_done'));
 496+ $j('#' + _this.clip_disp_ct + ' img').Jcrop({
 497+ onSelect: function(c){
 498+ js_log('on select:' + c.x +','+ c.y+','+ c.x2+','+ c.y2+','+ c.w+','+ c.h);
 499+ _this.rObj.crop = c;
 500+ },
 501+ onChange: function(c){
 502+ }
 503+ });
 504+ }
 505+ if(typeof $j.Jcrop == 'undefined'){
 506+ loadExternalCss( mv_embed_path + 'jquery/plugins/Jcrop/css/jquery.Jcrop.css');
 507+ //load the jcrop library if needed:
 508+ mvJsLoader.doLoad({'$j.Jcrop':'jquery/plugins/Jcrop/js/jquery.Jcrop.js'},function(){
 509+ doEnableCrop();
 510+ });
 511+ }else{
 512+ doEnableCrop();
 513+ }
 514+
 515+ }
 516+}
 517+
 518+
 519+
 520+// mv_lock_vid_updates defined in mv_stream.js (we need to do some more refactoring )
 521+if(typeof mv_lock_vid_updates == 'undefined')
 522+ mv_lock_vid_updates= false;
 523+
 524+function add_adjust_hooks(mvd_id){
 525+ js_log('add_adjust_hooks: ' + mvd_id );
 526+ //if options are unset populate functions:
 527+ //add mouse over end time frame highlight
 528+ $j('#mv_end_hr_'+mvd_id).hoverIntent({interval:200,over:function(){
 529+ //js_log('pre style: ' + $j(this).css('border'));
 530+ $j(this).css('border','solid red');
 531+ do_video_time_update( $j('#mv_end_hr_'+mvd_id).val(), $j('#mv_end_hr_'+mvd_id).val() );
 532+ },out:function(){
 533+ $j(this).css('border','solid black thin');
 534+ do_video_time_update($j('#mv_start_hr_'+mvd_id).val(), $j('#mv_end_hr_'+mvd_id).val() );
 535+ }});
 536+ //add onchange js hooks:
 537+ $j('.mv_adj_hr').change(function(){
 538+ //preserve track duration for nav and seq:
 539+ //ie seems to crash so no interface updates for IE for the time being
 540+ if(!$j.browser.msie){
 541+ if(mvd_id=='nav'||mvd_id=='seq'){
 542+ add_adjust_hooks(mvd_id);
 543+ }else{
 544+ add_adjust_hooks(mvd_id)
 545+ }
 546+ }
 547+ //update the video time for onChange
 548+ do_video_time_update($j('#mv_start_hr_'+mvd_id).val(), $j('#mv_end_hr_'+mvd_id).val() );
 549+ });
 550+ //read the ntp time from the fields
 551+ var start_sec = ntp2seconds( $j('#mv_start_hr_'+mvd_id).val() );
 552+ var end_sec = ntp2seconds( $j('#mv_end_hr_'+mvd_id).val() );
 553+ js_log('start_sec:'+start_sec + ' end: ' + end_sec);
 554+ if(start_sec > end_sec){
 555+ js_log('start > end : ' + start_sec + ' > ' + end_sec);
 556+ //update end time to start_time + 1 second
 557+ end_sec = parseInt(start_sec+1);
 558+ $j('#mv_end_hr_'+mvd_id).val(seconds2ntp(end_sec));
 559+ }
 560+
 561+ var duration = end_sec - start_sec;
 562+ //set the track duration as 2 min or 2*duration (whatever is longer)
 563+ var track_dur = (duration*2<120)?120:duration*2;
 564+
 565+ //set the base offset
 566+ if(start_sec==0){
 567+ var base_offset = 0
 568+ }else{
 569+ //make sure we won't go into negative with a 1/4 track offset
 570+ //alert('wtf:s:' + start_sec + '-' + (track_dur*.25) );
 571+ var base_offset= start_sec-(track_dur*.25);
 572+ //alert('wtf: '+ base_offset);
 573+ if(base_offset < 0)
 574+ base_offset=0;
 575+ //js_log('set base offset: '+track_dur +'* .25 = '+ parseInt(base_offset) );
 576+ }
 577+ js_log('BASE OFFSET: '+ base_offset);
 578+ //set the base offset / track_dur interface vars:
 579+ $j('#track_time_start_'+mvd_id).html( seconds2ntp(base_offset) );
 580+ $j('#track_time_end_'+mvd_id).html( seconds2ntp( base_offset+track_dur ));
 581+
 582+ //set up start /end slider values:
 583+ var slider_start = (start_sec - base_offset) / track_dur;
 584+ var slider_end = (end_sec - base_offset) / track_dur;
 585+ var slider_dur = slider_end -slider_start;
 586+ //clear out the existing effect if present
 587+ //if(mv_sliders[mvd_id])mv_sliders[mvd_id].dispose();
 588+
 589+ //update the slider values (left right)
 590+ track_width = $j('#container_track_'+mvd_id).width();
 591+
 592+ js_log('start: '+ slider_start + ' =' + (slider_start*track_width) +
 593+ ' se:'+ slider_end + ' =' + (slider_end*track_width) +
 594+ ' width would be: :' + Math.round((slider_end*track_width)-(slider_start*track_width)));
 595+
 596+ //if re-size width less than width of image bump it up:
 597+ var resize_width = Math.round((slider_end*track_width)-(slider_start*track_width));
 598+ if( resize_width < 17 ) resize_width=17;
 599+
 600+ $j('#resize_'+mvd_id).css({
 601+ left:Math.round(slider_start*track_width)+'px',
 602+ width: resize_width+'px'
 603+ });
 604+ js_log("track width: " + $j('#container_track_'+mvd_id).width() +
 605+ ' slider_width: ' + $j('#resize_'+mvd_id).width());
 606+ //add an additional flag
 607+ var cur_handle = '';
 608+ $j('.ui-resizable-handle').mousedown( function(){
 609+ js_log('hid: ' + this.id);
 610+ cur_handle = this.id;
 611+ });
 612+ org_start = org_end ='';
 613+ //jQuery slider:
 614+ $j('#resize_'+mvd_id).resizable({
 615+ minWidth: 10,
 616+ maxWidth: $j('#resize_'+mvd_id).width(),
 617+ minHeight: 20,
 618+ maxHeight: 20,
 619+ handles: {
 620+ e: '.ui-resizable-e',
 621+ w: '.ui-resizable-w'
 622+ },
 623+ start: function(e,ui) {
 624+ mv_lock_vid_updates=true;
 625+ org_start = $j('#mv_start_hr_'+mvd_id).val();
 626+ org_end = $j('#mv_end_hr_'+mvd_id).val();
 627+ //js_log("org maxWidth: " + ui.options.maxWidth);
 628+ right_x = ( $j('#resize_'+mvd_id).position().left+
 629+ $j('#resize_'+mvd_id).width()
 630+ );
 631+ /*js_log('left:' + $j('#resize_'+mvd_id).position().left + ' width: '+
 632+ * $j('#resize_'+mvd_id).width() + ' right_x:'+ right_x);
 633+ */
 634+ if(cur_handle.indexOf('handle1')!=-1){
 635+ ui.options.maxWidth= right_x;
 636+ }else{
 637+ ui.options.maxWidth= (
 638+ $j('#container_track_'+mvd_id).width() -
 639+ $j('#resize_'+mvd_id).position().left
 640+ );
 641+ }
 642+ js_log("updated maxWidth: " + ui.options.maxWidth);
 643+ //js_log('grabbed: ' + e.explicitOriginalTarget.id);
 644+ //console.log('start ', ui);
 645+ },
 646+ stop: function(e,ui) {
 647+ mv_lock_vid_updates=false;
 648+ //console.log('stop ', ui);
 649+ //return the non-adjusted to its original value:
 650+ if(cur_handle.indexOf('handle1')!=-1){
 651+ $j('#mv_end_hr_'+mvd_id).val(org_end);
 652+ }else{
 653+ $j('#mv_start_hr_'+mvd_id).val(org_start);
 654+ }
 655+ //update the clip
 656+ do_video_time_update($j('#mv_start_hr_'+mvd_id).val(), $j('#mv_end_hr_'+mvd_id).val() );
 657+ },
 658+ resize: function(e,ui) {
 659+ base_offset = ntp2seconds( $j('#track_time_start_'+mvd_id).html());
 660+ mv_slider_update_stats(mvd_id);
 661+ }
 662+ });
 663+ $j('#dragSpan_'+mvd_id).css('cursor','move');
 664+ $j('#resize_'+mvd_id).draggable({
 665+ axis:'x',
 666+ containment:'parent',
 667+ handle: "#dragSpan_"+mvd_id,
 668+ drag:function(e, ui){
 669+ mv_slider_update_stats(mvd_id, true);
 670+ },
 671+ stop:function(e,ui){
 672+ do_video_time_update($j('#mv_start_hr_'+mvd_id).val(), $j('#mv_end_hr_'+mvd_id).val() );
 673+ }
 674+ });
 675+ //store the necessary values in the slider obj
 676+ //mv_sliders[mvd_id]['base_offset']=base_offset;
 677+ //mv_sliders[mvd_id]['track_dur']=track_dur;
 678+ function mv_slider_update_stats(mvd_id, drag){
 679+ var update_start=update_end=false;
 680+ //only update the side we are dragging:
 681+ if(cur_handle.indexOf('handle1')!=-1){
 682+ update_start=true;
 683+ }else{
 684+ update_end=true;
 685+ }
 686+ if(drag)update_end=update_start=true;
 687+ if(update_end){
 688+ var end_time = base_offset + (track_dur *(($j('#resize_'+mvd_id).position().left +
 689+ $j('#resize_'+mvd_id).width()) /
 690+ $j('#container_track_'+mvd_id).width()));
 691+ if(end_time>(track_dur+base_offset))end_time=track_dur+base_offset;
 692+ $j('#mv_end_hr_'+mvd_id).val( seconds2ntp(end_time) );
 693+ }
 694+ if(update_start)
 695+ $j('#mv_start_hr_'+mvd_id).val( seconds2ntp(base_offset + (track_dur *($j('#resize_'+mvd_id).position().left /
 696+ $j('#container_track_'+mvd_id).width()) ) ));
 697+ }
 698+}
 699+function do_video_time_update(start_time, end_time, mvd_id) {
 700+ js_log('do_video_time_update: ' +start_time + end_time);
 701+ if(mv_lock_vid_updates==false){
 702+ //update the vid title:
 703+ $j('#mv_videoPlayerTime').html( start_time + ' to ' + end_time );
 704+ var ebvid = $j('#embed_vid').get(0);
 705+ if( ebvid ){
 706+ if(ebvid.isPaused())
 707+ ebvid.stop();
 708+ ebvid.updateVideoTime(start_time, end_time);
 709+ js_log('update thumb: '+ start_time);
 710+ ebvid.updateThumbTimeNTP( start_time );
 711+ }
 712+ }
 713+}
\ No newline at end of file
Property changes on: trunk/extensions/MetavidWiki/skins/mv_embed/libClipEdit/mv_clipedit.js
___________________________________________________________________
Name: svn:mergeinfo
1714 +
Name: svn:eol-style
2715 + native
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_embed_iframe.php
@@ -73,10 +73,39 @@
7474 <script type="text/javascript" src="mv_embed.js"></script>
7575 </head>
7676 <body>
77 - <video roe="<?php echo htmlspecialchars( $roe_url )?>" width="<?php echo htmlspecialchars( $width )?>"
 77+ <video roe="<?php echo escapeJsString( $roe_url )?>" width="<?php echo htmlspecialchars( $width )?>"
7878 height="<?php echo htmlspecialchars( $height )?>"></video>
7979 </body>
8080 </html>
8181 <?
8282 }
 83+
 84+/**
 85+ * JS escape function copied from MediaWiki's Xml::escapeJsString()
 86+ */
 87+function escapeJsString( $string ) {
 88+ // See ECMA 262 section 7.8.4 for string literal format
 89+ $pairs = array(
 90+ "\\" => "\\\\",
 91+ "\"" => "\\\"",
 92+ '\'' => '\\\'',
 93+ "\n" => "\\n",
 94+ "\r" => "\\r",
 95+
 96+ # To avoid closing the element or CDATA section
 97+ "<" => "\\x3c",
 98+ ">" => "\\x3e",
 99+
 100+ # To avoid any complaints about bad entity refs
 101+ "&" => "\\x26",
 102+
 103+ # Work around https://bugzilla.mozilla.org/show_bug.cgi?id=274152
 104+ # Encode certain Unicode formatting chars so affected
 105+ # versions of Gecko don't misinterpret our strings;
 106+ # this is a common problem with Farsi text.
 107+ "\xe2\x80\x8c" => "\\u200c", // ZERO WIDTH NON-JOINER
 108+ "\xe2\x80\x8d" => "\\u200d", // ZERO WIDTH JOINER
 109+ );
 110+ return strtr( $string, $pairs );
 111+}
83112 ?>
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_embed.js
@@ -22,7 +22,7 @@
2323 }
2424
2525 //used to grab fresh copies of scripts. (should be changed on commit)
26 -var MV_EMBED_VERSION = '1.0rc6';
 26+var MV_EMBED_VERSION = '1.0rc7';
2727
2828 //the name of the player skin (default is mvpcf)
2929 var mv_skin_name = 'mvpcf';
@@ -48,7 +48,7 @@
4949
5050 //get mv_embed location if it has not been set
5151 if( !mv_embed_path ){
52 - var mv_embed_path =getMvEmbedPath();
 52+ var mv_embed_path = getMvEmbedPath();
5353 }
5454 //set the unique request id (for ensuring fresh copies of scripts on updates)
5555 if( !mv_embed_urid ){
@@ -58,55 +58,65 @@
5959 //the default thumbnail for missing images:
6060 var mv_default_thumb_url = mv_embed_path + 'images/vid_default_thumb.jpg';
6161
 62+//init the global Msg if not already
6263 if(!gMsg){var gMsg={};}
 64+//laguage loader:
 65+function loadGM( msgSet ){
 66+ for(var i in msgSet){
 67+ gMsg[ i ] = msgSet[i];
 68+ }
 69+}
 70+
6371 //all default msg in [English] should be overwritten by the CMS language msg system.
64 -gMsg['loading_txt'] = 'loading <blink>...</blink>';
65 -gMsg['loading_plugin'] = 'loading plugin<blink>...</blink>';
66 -gMsg['select_playback'] = 'Set Playback Preference';
67 -gMsg['link_back'] = 'Link Back';
68 -gMsg['error_load_lib'] = 'mv_embed: Unable to load required javascript libraries\n'+
69 - 'insert script via DOM has failed, try reloading? ';
70 -
71 -gMsg['error_swap_vid'] = 'Error:mv_embed was unable to swap the video tag for the mv_embed interface';
 72+loadGM( {
 73+ 'loading_txt':'loading <blink>...</blink>',
 74+ 'loading_plugin' : 'loading plugin<blink>...</blink>',
 75+ 'select_playback' : 'Set Playback Preference',
 76+ 'link_back' : 'Link Back',
 77+ 'error_load_lib' : 'mv_embed: Unable to load required javascript libraries\n'+
 78+ 'insert script via DOM has failed, try reloading? ',
 79+
 80+ 'error_swap_vid' : 'Error:mv_embed was unable to swap the video tag for the mv_embed interface',
 81+
 82+ 'download_segment' : 'Download Selection:',
 83+ 'download_full' : 'Download Full Video File:',
 84+ 'download_clip' : 'Download the Clip',
 85+ 'download_text' : 'Download Text (<a style="color:white" title="cmml" href="http://wiki.xiph.org/index.php/CMML">cmml</a> xml):',
 86+
 87+ 'clip_linkback' : 'Clip Source Page',
 88+ //plugin names:
 89+ 'ogg-player-vlc-mozilla' : 'VLC Plugin',
 90+ 'ogg-player-videoElement' : 'Native Ogg Video Support',
 91+ 'ogg-player-vlc-activex' : 'VLC ActiveX',
 92+ 'ogg-player-oggPlay' : 'Annodex OggPlay Plugin',
 93+ 'ogg-player-oggPlugin' : 'Generic Ogg Plugin',
 94+ 'ogg-player-quicktime-mozilla' : 'Quicktime Plugin',
 95+ 'ogg-player-quicktime-activex' : 'Quicktime ActiveX',
 96+ 'ogg-player-cortado' : 'Java Cortado',
 97+ 'ogg-player-flowplayer' : 'Flowplayer',
 98+ 'ogg-player-selected' : ' (selected)',
 99+ 'generic_missing_plugin' : 'You browser does not appear to support playback type: <b>$1</b><br>' +
 100+ 'visit the <a href="http://metavid.org/wiki/Client_Playback">Playback Methods</a> page to download a player<br>',
 101+
 102+ 'add_to_end_of_sequence' : 'Add to End of Sequence',
 103+
 104+ 'missing_video_stream' : 'The video file for this stream is missing',
 105+
 106+ 'select_transcript_set' : 'Select Text Layers',
 107+ 'auto_scroll' : 'auto scroll',
 108+ 'close' : 'close',
 109+ 'improve_transcript' : 'Improve Transcript',
 110+
 111+ 'next_clip_msg' : 'Play Next Clip',
 112+ 'prev_clip_msg' : 'Play Previous Clip',
 113+ 'current_clip_msg' : 'Continue Playing this Clip',
 114+
 115+ 'seek_to' : 'Seek to'
 116+ }
 117+);
72118
73 -gMsg['download_segment'] = 'Download Selection:';
74 -gMsg['download_full'] = 'Download Full Video File:'
75 -gMsg['download_clip'] = 'Download the Clip';
76 -gMsg['download_text'] = 'Download Text (<a style="color:white" title="cmml" href="http://wiki.xiph.org/index.php/CMML">cmml</a> xml):';
77 -
78 -gMsg['clip_linkback'] = 'Clip Source Page';
79 -//plugin names:
80 -gMsg['ogg-player-vlc-mozilla'] = 'VLC Plugin';
81 -gMsg['ogg-player-videoElement'] = 'Native Ogg Video Support';
82 -gMsg['ogg-player-vlc-activex'] = 'VLC ActiveX';
83 -gMsg['ogg-player-oggPlay'] = 'Annodex OggPlay Plugin';
84 -gMsg['ogg-player-oggPlugin'] = 'Generic Ogg Plugin';
85 -gMsg['ogg-player-quicktime-mozilla'] = 'Quicktime Plugin';
86 -gMsg['ogg-player-quicktime-activex'] = 'Quicktime ActiveX';
87 -gMsg['ogg-player-cortado'] = 'Java Cortado';
88 -gMsg['ogg-player-flowplayer'] = 'Flowplayer';
89 -gMsg['ogg-player-selected'] = ' (selected)';
90 -gMsg['generic_missing_plugin'] = 'You browser does not appear to support playback type: <b>$1</b><br>' +
91 - 'visit the <a href="http://metavid.org/wiki/Client_Playback">Playback Methods</a> page to download a player<br>';
92 -
93 -gMsg['add_to_end_of_sequence'] = 'Add to End of Sequence';
94 -
95 -gMsg['missing_video_stream'] = 'The video file for this stream is missing';
96 -
97 -gMsg['select_transcript_set'] = 'Select Text Layers';
98 -gMsg['auto_scroll'] = 'auto scroll';
99 -gMsg['close'] = 'close';
100 -gMsg['improve_transcript'] = 'Improve Transcript';
101 -
102 -gMsg['next_clip_msg'] = 'Play Next Clip';
103 -gMsg['prev_clip_msg'] = 'Play Previous Clip';
104 -gMsg['current_clip_msg'] = 'Continue Playing this Clip';
105 -
106 -gMsg['seek_to'] = 'Seek to';
107 -
108 -//grabs from the globalMsg obj
109 -//@@todo integrate msg serving into script loader
110 -function getMsg( key , args ) {
 119+//get a language messege
 120+function gM( key , args ) {
111121 if ( key in gMsg ) {
112122 if(typeof args == 'object'){
113123 for(var v in args){
@@ -177,7 +187,7 @@
178188
179189 /*********** INITIALIZATION CODE *************
180190 * the mvEmbed object drives basic loading of libs
181 - * its load_libs function will be called during initialization
 191+ * its load_libs function will be called if mv_embed is to be used on a given page
182192 *********************************************/
183193 var mvEmbed = {
184194 Version: MV_EMBED_VERSION,
@@ -188,10 +198,12 @@
189199 loading:false,
190200 libs_loaded:false,
191201 //plugin libs var names and paths:
192 - lib_jquery:{'window.jQuery':'jquery/jquery-1.2.6.js'},
 202+ lib_base:{
 203+ 'window.jQuery' :'jquery/jquery-1.2.6.js',
 204+ 'embedVideo' :'libEmbedObj/mv_baseEmbed.js'
 205+ },
193206 lib_plugins:{
194 - '$j.ui.mouse' :'jquery/jquery.ui-1.5.2/ui/minified/ui.core.min.js', //load the core ui
195 - '$j.secureEvalJSON' :'jquery/plugins/jquery.json-1.3.min.js' //load json lib for *more* trusted JSON evals
 207+ '$j.ui.mouse' :'jquery/jquery.ui-1.5.2/ui/minified/ui.core.min.js', //load the core ui
196208 },
197209 // not used:
198210 //'$j.timer.global':'jquery/plugins/jquery.timers.js',
@@ -216,7 +228,7 @@
217229 }
218230 //two loading stages, first get jQuery
219231 var _this = this;
220 - mvJsLoader.doLoad(this.lib_jquery,function(){
 232+ mvJsLoader.doLoad(this.lib_base,function(){
221233 js_log("type of " + typeof window.jQuery);
222234 //once jQuery is loaded set up no conflict & load plugins:
223235 _global['$j'] = jQuery.noConflict();
@@ -313,7 +325,7 @@
314326 },
315327 getName : function()
316328 {
317 - return getMsg('ogg-player-' + this.id);
 329+ return gM('ogg-player-' + this.id);
318330 },
319331 load : function(callback)
320332 {
@@ -636,7 +648,7 @@
637649
638650 embedObj.jump_time = seconds2ntp( parseInt( embedObj.getDuration() * perc ) + embedObj.start_time_sec);
639651 //js_log('perc:' + perc + ' * ' + embedObj.getDuration() + ' jt:'+ this.jump_time);
640 - embedObj.setStatus( getMsg('seek_to')+' '+embedObj.jump_time );
 652+ embedObj.setStatus( gM('seek_to')+' '+embedObj.jump_time );
641653 //update the thumbnail / frame
642654 if(embedObj.isPlaying==false){
643655 embedObj.updateThumbPerc( perc );
@@ -925,7 +937,7 @@
926938 }
927939 if(loading){
928940 if( this.load_time++ > 2000){ //time out after ~50seconds
929 - js_error( getMsg('error_load_lib') + cur_path);
 941+ js_error( gM('error_load_lib') + cur_path);
930942 this.load_error=true;
931943 }else{
932944 setTimeout('mvJsLoader.doLoad()',25);
@@ -969,13 +981,12 @@
970982 js_log("mv_init_done do nothing...");
971983 return false;
972984 }
973 -
974985 mv_init_done=true;
975986 //check if this page does have video or playlist
976987 if(document.getElementsByTagName("video").length!=0 ||
977988 document.getElementsByTagName("playlist").length!=0){
978989 js_log('we have vids to process');
979 - //load libaries
 990+ //load libs
980991 mvEmbed.load_libs();
981992 }else{
982993 js_log('no video or playlist on the page... (done)');
@@ -985,7 +996,6 @@
986997 }
987998 }
988999 }
989 -
9901000 /*
9911001 * this function allows for targeted rewriting
9921002 */
@@ -1045,7 +1055,7 @@
10461056 global_player_list.push( $j(this).attr("id") );
10471057 //add loading: (pre-loading div)
10481058 /*$j(this).after('<div id="pre_loading_div_'+elm_id + '">'+
1049 - getMsg('loading_txt')+'</div>' );
 1059+ gM('loading_txt')+'</div>' );
10501060 */
10511061
10521062 //if video doSwap
@@ -1686,1215 +1696,6 @@
16871697 }
16881698 }
16891699 };
1690 -
1691 -/** base embedVideo object
1692 - @param element <video> tag used for initialization.
1693 - @constructor
1694 -*/
1695 -var embedVideo = function(element) {
1696 - return this.init(element);
1697 -};
1698 -
1699 -embedVideo.prototype = {
1700 - /** The mediaElement object containing all mediaSource objects */
1701 - media_element:null,
1702 - preview_mode:false,
1703 - slider:null,
1704 - ready_to_play:false, //should use html5 ready state
1705 - load_error:false, //used to set error in case of error
1706 - loading_external_data:false,
1707 - thumbnail_updating:false,
1708 - thumbnail_disp:true,
1709 - init_with_sources_loadedDone:false,
1710 - inDOM:false,
1711 - //for onClip done stuff:
1712 - anno_data_cache:null,
1713 - seek_time_sec:0,
1714 - base_seeker_slider_offset:null,
1715 - onClipDone_disp:false,
1716 - supports:{},
1717 - //for seek thumb updates:
1718 - cur_thumb_seek_time:0,
1719 - thumb_seek_interval:null,
1720 - //set the buffered percent:
1721 - bufferedPercent:0,
1722 - //utility functions for property values:
1723 - hx : function ( s ) {
1724 - if ( typeof s != 'String' ) {
1725 - s = s.toString();
1726 - }
1727 - return s.replace( /&/g, '&amp;' )
1728 - . replace( /</g, '&lt;' )
1729 - . replace( />/g, '&gt;' );
1730 - },
1731 - hq : function ( s ) {
1732 - return '"' + this.hx( s ) + '"';
1733 - },
1734 - playerPixelWidth : function()
1735 - {
1736 - var player = $j('#mv_embedded_player_'+this.id).get(0);
1737 - if(typeof player!='undefined' && player['offsetWidth'])
1738 - return player.offsetWidth;
1739 - else
1740 - return parseInt(this.width);
1741 - },
1742 - playerPixelHeight : function()
1743 - {
1744 - var player = $j('#mv_embedded_player_'+this.id).get(0);
1745 - if(typeof player!='undefined' && player['offsetHeight'])
1746 - return player.offsetHeight;
1747 - else
1748 - return parseInt(this.height);
1749 - },
1750 - init: function(element){
1751 - //this.element_pointer = element;
1752 -
1753 - //inherit all the default video_attributes
1754 - for(var attr in default_video_attributes){ //for in loop oky on user object
1755 - if(element.getAttribute(attr)){
1756 - this[attr]=element.getAttribute(attr);
1757 - //js_log('attr:' + attr + ' val: ' + video_attributes[attr] +" "+'elm_val:' + element.getAttribute(attr) + "\n (set by elm)");
1758 - }else{
1759 - this[attr]=default_video_attributes[attr];
1760 - //js_log('attr:' + attr + ' val: ' + video_attributes[attr] +" "+ 'elm_val:' + element.getAttribute(attr) + "\n (set by attr)");
1761 - }
1762 - }
1763 - if( this.duration!=null && this.duration.split(':').length >= 2)
1764 - this.duration = ntp2seconds( this.duration );
1765 -
1766 - //if style is set override width and height
1767 - var dwh = mv_default_video_size.split('x');
1768 - this.width = element.style.width ? element.style.width : dwh[0];
1769 - this.height = element.style.height ? element.style.height : dwh[1];
1770 - //set the plugin id
1771 - this.pid = 'pid_' + this.id;
1772 -
1773 - //grab any innerHTML and set it to missing_plugin_html
1774 - //@@todo we should strip source tags instead of checking and skipping
1775 - if(element.innerHTML!='' && element.getElementsByTagName('source').length==0){
1776 - js_log('innerHTML: ' + element.innerHTML);
1777 - this.user_missing_plugin_html=element.innerHTML;
1778 - }
1779 - // load all of the specified sources
1780 - this.media_element = new mediaElement(element);
1781 - },
1782 - on_dom_swap: function(){
1783 - js_log('f:on_dom_swap');
1784 - // Process the provided ROE file... if we don't yet have sources
1785 - if(this.roe && this.media_element.sources.length==0 ){
1786 - js_log('loading external data');
1787 - this.loading_external_data=true;
1788 - var _this = this;
1789 - do_request(this.roe, function(data)
1790 - {
1791 - //continue
1792 - _this.media_element.addROE(data);
1793 - js_log('added_roe::' + _this.media_element.sources.length);
1794 -
1795 - js_log('set loading_external_data=false');
1796 - _this.loading_external_data=false;
1797 -
1798 - _this.init_with_sources_loaded();
1799 - });
1800 - }
1801 - },
1802 - init_with_sources_loaded : function()
1803 - {
1804 - js_log('f:init_with_sources_loaded');
1805 - //set flag that we have run this function:
1806 - this.init_with_sources_loadedDone=true;
1807 - //autoseletct the source
1808 - this.media_element.autoSelectSource();
1809 - //auto select player based on prefrence or default order
1810 - if( !this.media_element.selected_source )
1811 - {
1812 - //check for parent clip:
1813 - if( typeof this.pc != 'undefined' ){
1814 - js_log('no sources, type:' +this.type + ' check for html');
1815 - //do load player if just displaying innerHTML:
1816 - if(this.pc.type =='text/html'){
1817 - this.selected_player = embedTypes.players.defaultPlayer( 'text/html' );
1818 - js_log('set selected player:'+ this.selected_player.mime_type);
1819 - }
1820 - }
1821 - }else{
1822 - this.selected_player = embedTypes.players.defaultPlayer( this.media_element.selected_source.mime_type );
1823 - }
1824 - if( this.selected_player ){
1825 - js_log('selected ' + this.selected_player.getName());
1826 - js_log("PLAYBACK TYPE: "+this.selected_player.library);
1827 - this.thumbnail_disp = true;
1828 - this.inheritEmbedObj();
1829 - }else{
1830 - //no source's playable
1831 - var missing_type ='';
1832 - var or ='';
1833 - for( var i=0; i < this.media_element.sources.length; i++){
1834 - missing_type+=or + this.media_element.sources[i].mime_type;
1835 - or=' or ';
1836 - }
1837 - if( this.pc )
1838 - var missing_type = this.pc.type;
1839 -
1840 - js_log('no player found for given source type ' + missing_type);
1841 - this.load_error= getMsg('generic_missing_plugin', missing_type );
1842 - }
1843 - },
1844 - inheritEmbedObj:function(){
1845 - //@@note: tricky cuz direct overwrite is not so ideal.. since the extended object is already tied to the dom
1846 - //clear out any non-base embedObj stuff:
1847 - if(this.instanceOf){
1848 - eval('tmpObj = '+this.instanceOf);
1849 - for(var i in tmpObj){ //for in loop oky for object
1850 - if(this['parent_'+i]){
1851 - this[i]=this['parent_'+i];
1852 - }else{
1853 - this[i]=null;
1854 - }
1855 - }
1856 - }
1857 - //set up the new embedObj
1858 - js_log('f: inheritEmbedObj: embedding with ' + this.selected_player.library);
1859 - var _this = this;
1860 - this.selected_player.load( function()
1861 - {
1862 - //js_log('inheriting '+_this.selected_player.library +'Embed to ' + _this.id + ' ' + $j('#'+_this.id).length);
1863 - //var _this = $j('#'+_this.id).get(0);
1864 - //js_log( 'type of ' + _this.selected_player.library +'Embed + ' +
1865 - // eval('typeof '+_this.selected_player.library +'Embed'));
1866 - eval('embedObj = ' +_this.selected_player.library +'Embed;');
1867 - for(var method in embedObj){ //for in loop oky for object
1868 - //parent method preservation for local overwritten methods
1869 - if(_this[method])
1870 - _this['parent_' + method] = _this[method];
1871 - _this[method]=embedObj[method];
1872 - }
1873 - js_log('TYPEOF_ppause: ' + typeof _this['parent_pause']);
1874 -
1875 - if(_this.inheritEmbedOverride){
1876 - _this.inheritEmbedOverride();
1877 - }
1878 - //update controls if possible
1879 - if(!_this.loading_external_data)
1880 - _this.refreshControlsHTML();
1881 -
1882 - //js_log("READY TO PLAY:"+_this.id);
1883 - _this.ready_to_play=true;
1884 - _this.getDuration();
1885 - _this.getHTML();
1886 - });
1887 - },
1888 - selectPlayer:function(player)
1889 - {
1890 - var _this = this;
1891 - if(this.selected_player.id != player.id){
1892 - this.selected_player = player;
1893 - this.inheritEmbedObj();
1894 - }
1895 - },
1896 - getTimeReq:function(){
1897 - js_log('f:getTimeReq:'+ this.getDurationNTP());
1898 - var default_time_req = '0:00:00/' + this.getDurationNTP() ;
1899 - if(!this.media_element)
1900 - return default_time_req;
1901 - if(!this.media_element.selected_source)
1902 - return default_time_req;
1903 - if(!this.media_element.selected_source.end_ntp)
1904 - return default_time_req;
1905 - return this.media_element.selected_source.start_ntp+'/'+this.media_element.selected_source.end_ntp;
1906 - },
1907 - getDuration:function(){
1908 - //update some local pointers for the selected source:
1909 - if( this.media_element.selected_source.duration &&
1910 - this.media_element.selected_source.duration != 0 ){
1911 - this.duration = this.media_element.selected_source.duration;
1912 - this.start_offset = this.media_element.selected_source.start_offset;
1913 - this.start_ntp = this.media_element.selected_source.start_ntp;
1914 - this.end_ntp = this.media_element.selected_source.end_ntp;
1915 - }else{
1916 - //update start end_ntp if duration !=0 (set from plugin)
1917 - if(this.duration && this.duration !=0){
1918 - this.start_ntp = '0:0:0';
1919 - this.end_ntp = seconds2ntp( this.duration );
1920 - }
1921 - }
1922 - //return the duration
1923 - return this.duration;
1924 - },
1925 - /* get the duration in ntp format */
1926 - getDurationNTP:function(){
1927 - return seconds2ntp(this.getDuration());
1928 - },
1929 - /*
1930 - * wrapEmebedContainer
1931 - * wraps the embed code into a container to better support playlist function
1932 - * (where embed element is swapped for next clip
1933 - * (where plugin method does not support playlsits)
1934 - */
1935 - wrapEmebedContainer:function(embed_code){
1936 - //check if parent clip is set( ie we are in a playlist so name the embed container by playlistID)
1937 - var id = (this.pc!=null)?this.pc.pp.id:this.id;
1938 - return '<div id="mv_ebct_'+id+'" style="width:'+this.width+'px;height:'+this.height+'px;">' +
1939 - embed_code +
1940 - '</div>';
1941 - },
1942 - getEmbedHTML : function(){
1943 - //return this.wrapEmebedContainer( this.getEmbedObj() );
1944 - return 'function getEmbedHTML should be overitten by embedLib ';
1945 - },
1946 - //do seek function (should be overwritten by implementing embedLibs)
1947 - // first check if seek can be done on locally downloaded content.
1948 - doSeek : function( perc ){
1949 - js_log('f:mv_embed:doSeek:'+perc);
1950 - if( this.supportsURLTimeEncoding() ){
1951 - js_log('Seeking to ' + this.seek_time_sec + ' (local copy of clip not loaded at' + perc + '%)');
1952 - this.stop();
1953 - this.didSeekJump=true;
1954 - //update the slider
1955 - this.setSliderValue( perc );
1956 - }
1957 -
1958 - //do play in 100ms (give things time to clear)
1959 - setTimeout('$j(\'#' + this.id + '\').get(0).play()',100);
1960 - },
1961 - doEmbedHTML:function()
1962 - {
1963 - js_log('f:doEmbedHTML');
1964 - js_log('thum disp:'+this.thumbnail_disp);
1965 - var _this = this;
1966 - this.closeDisplayedHTML();
1967 -
1968 -// if(!this.selected_player){
1969 -// return this.getPluginMissingHTML();
1970 - //Set "loading" here
1971 - $j('#mv_embedded_player_'+_this.id).html(''+
1972 - '<div style="color:black;width:'+this.width+'px;height:'+this.height+'px;">' +
1973 - getMsg('loading_plugin') +
1974 - '</div>'
1975 - );
1976 - // schedule embedding
1977 - this.selected_player.load(function()
1978 - {
1979 - js_log('performing embed for ' + _this.id);
1980 - var embed_code = _this.getEmbedHTML();
1981 - //js_log(embed_code);
1982 - $j('#mv_embedded_player_'+_this.id).html(embed_code);
1983 - });
1984 - },
1985 - /* todo abstract out onClipDone chain of functions and merge with textInterface */
1986 - onClipDone:function(){
1987 - //stop the clip (load the thumbnail etc)
1988 - this.stop();
1989 - var _this = this;
1990 -
1991 - //if the clip resolution is < 320 don't do fancy onClipDone stuff
1992 - if(this.width<300){
1993 - return ;
1994 - }
1995 - this.onClipDone_disp=true;
1996 - this.thumbnail_disp=true;
1997 - //make sure we are not in preview mode( no end clip actions in preview mode)
1998 - if( this.preview_mode )
1999 - return ;
2000 -
2001 - $j('#img_thumb_'+this.id).css('zindex',1);
2002 - $j('#big_play_link_'+this.id).hide();
2003 - //add the liks_info_div black back
2004 - $j('#dc_'+this.id).append('<div id="liks_info_'+this.id+'" ' +
2005 - 'style="width:' +parseInt(parseInt(this.width)/2)+'px;'+
2006 - 'height:'+ parseInt(parseInt(this.height)) +'px;'+
2007 - 'position:absolute;top:10px;overflow:auto'+
2008 - 'width: '+parseInt( ((parseInt(this.width)/2)-15) ) + 'px;'+
2009 - 'left:'+ parseInt( ((parseInt(this.width)/2)+15) ) +'px;">'+
2010 - '</div>' +
2011 - '<div id="black_back_'+this.id+'" ' +
2012 - 'style="z-index:-2;position:absolute;background:#000;' +
2013 - 'top:0px;left:0px;width:'+parseInt(this.width)+'px;' +
2014 - 'height:'+parseInt(this.height)+'px;">' +
2015 - '</div>'
2016 - );
2017 -
2018 - //start animation (make thumb small in upper left add in div for "loading"
2019 - $j('#img_thumb_'+this.id).animate({
2020 - width:parseInt(parseInt(_this.width)/2),
2021 - height:parseInt(parseInt(_this.height)/2),
2022 - top:20,
2023 - left:10
2024 - },
2025 - 1000,
2026 - function(){
2027 - //animation done.. add "loading" to div if empty
2028 - if($j('#liks_info_'+_this.id).html()==''){
2029 - $j('#liks_info_'+_this.id).html(getMsg('loading_txt'));
2030 - }
2031 - }
2032 - )
2033 - //now load roe if run the showNextPrevLinks
2034 - if(this.roe && this.media_element.addedROEData==false){
2035 - do_request(this.roe, function(data)
2036 - {
2037 - _this.media_element.addROE(data);
2038 - _this.getNextPrevLinks();
2039 - });
2040 - }else{
2041 - this.getNextPrevLinks();
2042 - }
2043 - },
2044 - //@@todo we should merge getNextPrevLinks with textInterface .. there is repeated code between them.
2045 - getNextPrevLinks:function(){
2046 - js_log('f:getNextPrevLinks');
2047 - var anno_track_url = null;
2048 - var _this = this;
2049 - //check for annoative track
2050 - $j.each(this.media_element.sources, function(inx, n){
2051 - if(n.mime_type=='text/cmml'){
2052 - if( n.id == 'Anno_en'){
2053 - anno_track_url = n.src;
2054 - }
2055 - }
2056 - });
2057 - if( anno_track_url ){
2058 - js_log('found annotative track:'+ anno_track_url);
2059 - //zero out seconds (should improve cache hit rate and generally expands metadata search)
2060 - //@@todo this could be repalced with a regExp
2061 - var annoURL = parseUri(anno_track_url);
2062 - var times = annoURL.queryKey['t'].split('/');
2063 - var stime_parts = times[0].split(':');
2064 - var etime_parts = times[1].split(':');
2065 - //zero out the hour:
2066 - var new_start = stime_parts[0]+':'+'0:0';
2067 - //zero out the end sec
2068 - var new_end = (etime_parts[0]== stime_parts[0])? (etime_parts[0]+1)+':0:0' :etime_parts[0]+':0:0';
2069 -
2070 - var etime_parts = times[1].split(':');
2071 -
2072 - var new_anno_track_url = annoURL.protocol +'://'+ annoURL.host + annoURL.path +'?';
2073 - $j.each(annoURL.queryKey, function(i, val){
2074 - new_anno_track_url +=(i=='t')?'t='+new_start+'/'+new_end +'&' :
2075 - i+'='+ val+'&';
2076 - });
2077 - var request_key = new_start+'/'+new_end;
2078 - //check the anno_data cache:
2079 - //@@todo search cache see if current is in range.
2080 - if(this.anno_data_cache){
2081 - js_log('anno data found in cache: '+request_key);
2082 - this.showNextPrevLinks();
2083 - }else{
2084 - do_request(new_anno_track_url, function(cmml_data){
2085 - js_log('raw response: '+ cmml_data);
2086 - if(typeof cmml_data == 'string')
2087 - {
2088 - var parser=new DOMParser();
2089 - js_log('Parse CMML data:' + cmml_data);
2090 - cmml_data=parser.parseFromString(cmml_data,"text/xml");
2091 - }
2092 - //init anno_data_cache
2093 - if(!_this.anno_data_cache)
2094 - _this.anno_data_cache={};
2095 - //grab all metadata and put it into the anno_data_cache:
2096 - $j.each(cmml_data.getElementsByTagName('clip'), function(inx, clip){
2097 - _this.anno_data_cache[ $j(clip).attr("id") ]={
2098 - 'start_time_sec':ntp2seconds($j(clip).attr("start").replace('npt:','')),
2099 - 'end_time_sec':ntp2seconds($j(clip).attr("end").replace('npt:','')),
2100 - 'time_req':$j(clip).attr("start").replace('npt:','')+'/'+$j(clip).attr("end").replace('npt:','')
2101 - };
2102 - //grab all its meta
2103 - _this.anno_data_cache[ $j(clip).attr("id") ]['meta']={};
2104 - $j.each(clip.getElementsByTagName('meta'),function(imx, meta){
2105 - //js_log('adding meta: '+ $j(meta).attr("name")+ ' = '+ $j(meta).attr("content"));
2106 - _this.anno_data_cache[$j(clip).attr("id")]['meta'][$j(meta).attr("name")]=$j(meta).attr("content");
2107 - });
2108 - });
2109 - _this.showNextPrevLinks();
2110 - });
2111 - }
2112 - }else{
2113 - js_log('no annotative track found');
2114 - $j('#liks_info_'+this.id).html('no metadata found for next, previous links');
2115 - }
2116 - //query current request time +|- 60s to get prev next speech links.
2117 - },
2118 - showNextPrevLinks:function(){
2119 - js_log('f:showNextPrevLinks');
2120 - //int requested links:
2121 - var link = {
2122 - 'prev':'',
2123 - 'current':'',
2124 - 'next':''
2125 - }
2126 - var curTime = this.getTimeReq().split('/');
2127 -
2128 - var s_sec = ntp2seconds(curTime[0]);
2129 - var e_sec = ntp2seconds(curTime[1]);
2130 - js_log('showNextPrevLinks: req time: '+ s_sec + ' to ' + e_sec);
2131 - //now we have all the data in anno_data_cache
2132 - var current_done=false;
2133 - for(var clip_id in this.anno_data_cache){ //for in loop oky for object
2134 - var clip = this.anno_data_cache[clip_id];
2135 - //js_log('on clip:'+ clip_id);
2136 - //set prev_link (if cur_link is still empty)
2137 - if( s_sec > clip.end_time_sec){
2138 - link.prev = clip_id;
2139 - js_log('showNextPrevLinks: ' + s_sec + ' < ' + clip.end_time_sec + ' set prev');
2140 - }
2141 -
2142 - if(e_sec==clip.end_time_sec && s_sec== clip.start_time_sec)
2143 - current_done = true;
2144 - //current clip is not done:
2145 - if( e_sec < clip.end_time_sec && link.current=='' && !current_done){
2146 - link.current = clip_id;
2147 - js_log('showNextPrevLinks: ' + e_sec + ' < ' + clip.end_time_sec + ' set current');
2148 - }
2149 -
2150 - //set end clip (first clip where start time is > end_time of req
2151 - if( e_sec < clip.start_time_sec && link.next==''){
2152 - link.next = clip_id;
2153 - js_log('showNextPrevLinks: '+ e_sec + ' < '+ clip.start_time_sec + ' && ' + link.next );
2154 - }
2155 - }
2156 - var html='';
2157 - if(link.prev=='' && link.current=='' && link.next==''){
2158 - html='<p><a href="'+this.media_element.linkbackgetMsg+'">clip page</a>';
2159 - }else{
2160 - for(var link_type in link){
2161 - var link_id = link[link_type];
2162 - if(link_id!=''){
2163 - var clip = this.anno_data_cache[link_id];
2164 - var title_msg='';
2165 - for(var j in clip['meta']){
2166 - title_msg+=j.replace(/_/g,' ') +': ' +clip['meta'][j].replace(/_/g,' ') +" <br>";
2167 - }
2168 - var time_req = clip.time_req;
2169 - if(link_type=='current') //if current start from end of current clip play to end of current meta:
2170 - time_req = curTime[1]+ '/' + seconds2ntp( clip.end_time_sec );
2171 -
2172 - //do special linkbacks for metavid content:
2173 - var regTimeCheck = new RegExp(/[0-9]+:[0-9]+:[0-9]+\/[0-9]+:[0-9]+:[0-9]+/);
2174 - html+='<p><a ';
2175 - if( regTimeCheck.test( this.media_element.linkback ) ){
2176 - html+=' href="'+ this.media_element.linkback.replace(regTimeCheck,time_req) +'" ';
2177 - }else{
2178 - html+=' href="#" onClick="$j(\'#'+this.id+'\').get(0).playByTimeReq(\''+
2179 - time_req + '\'); return false; "';
2180 - }
2181 - html+=' title="' + title_msg + '">' +
2182 - getMsg(link_type+'_clip_msg') +
2183 - '</a><br><span style="font-size:small">'+ title_msg +'<span></p>';
2184 - }
2185 - }
2186 - }
2187 - //js_og("should set html:"+ html);
2188 - $j('#liks_info_'+this.id).html(html);
2189 - },
2190 - playByTimeReq: function(time_req){
2191 - js_log('f:playByTimeReq: '+time_req );
2192 - this.stop();
2193 - this.updateVideoTimeReq(time_req);
2194 - this.play();
2195 - },
2196 - doThumbnailHTML:function()
2197 - {
2198 - var _this = this;
2199 - js_log('f:doThumbnailHTML'+ this.thumbnail_disp);
2200 - this.closeDisplayedHTML();
2201 - this.thumbnail_disp = true;
2202 -
2203 - $j('#mv_embedded_player_'+this.id).html( this.getThumbnailHTML() );
2204 - this.paused = true;
2205 - },
2206 - refreshControlsHTML:function(){
2207 - js_log('refreshing controls HTML');
2208 - if($j('#mv_embedded_controls_'+this.id).length==0)
2209 - {
2210 - js_log('#mv_embedded_controls_'+this.id + ' not present, returning');
2211 - return;
2212 - }else{
2213 - $j('#mv_embedded_controls_'+this.id).html( this.getControlsHTML() );
2214 - ctrlBuilder.addControlHooks(this);
2215 - }
2216 - },
2217 - getControlsHTML:function()
2218 - {
2219 - return ctrlBuilder.getControls( this );
2220 - },
2221 - getHTML : function (){
2222 - //@@todo check if we have sources avaliable
2223 - js_log('f:getHTML : ' + this.id );
2224 - var _this = this;
2225 - var html_code = '';
2226 - html_code = '<div id="videoPlayer_'+this.id+'" style="width:'+this.width+'px;" class="videoPlayer">';
2227 - html_code += '<div style="width:'+parseInt(this.width)+'px;height:'+parseInt(this.height)+'px;" id="mv_embedded_player_'+this.id+'">' +
2228 - this.getThumbnailHTML() +
2229 - '</div>';
2230 - //js_log("mvEmbed:controls "+ typeof this.controls);
2231 - if(this.controls)
2232 - {
2233 - js_log("f:getHTML:AddControls");
2234 - html_code +='<div id="mv_embedded_controls_' + this.id + '" class="controls" style="width:' + this.width + 'px">';
2235 - html_code += this.getControlsHTML();
2236 - html_code +='</div>';
2237 - //block out some space by encapulating the top level div
2238 - $j(this).wrap('<div style="width:'+parseInt(this.width)+'px;height:'
2239 - +(parseInt(this.height)+ctrlBuilder.height)+'px"></div>');
2240 - }
2241 - html_code += '</div>'; //videoPlayer div close
2242 - //js_log('should set: '+this.id);
2243 - $j(this).html( html_code );
2244 - //add hooks once Controls are in DOM
2245 - ctrlBuilder.addControlHooks(this);
2246 -
2247 - //js_log('set this to: ' + $j(this).html() );
2248 - //alert('stop');
2249 - //if auto play==true directly embed the plugin
2250 - if(this.autoplay)
2251 - {
2252 - js_log('activating autoplay');
2253 - this.play();
2254 - }
2255 - },
2256 - /*
2257 - * get missing plugin html (check for user included code)
2258 - */
2259 - getPluginMissingHTML : function(){
2260 - //keep the box width hight:
2261 - var out = '<div style="width:'+this.width+'px;height:'+this.height+'px">';
2262 - if(this.user_missing_plugin_html){
2263 - out+= this.user_missing_plugin_html;
2264 - }else{
2265 - out+= getMsg('generic_missing_plugin') + ' or <a title="'+getMsg('download_clip')+'" href="'+this.src +'">'+getMsg('download_clip')+'</a>';
2266 - }
2267 - return out + '</div>';
2268 - },
2269 - updateVideoTimeReq:function(time_req){
2270 - js_log('f:updateVideoTimeReq');
2271 - var time_parts =time_req.split('/');
2272 - this.updateVideoTime(time_parts[0], time_parts[1]);
2273 - },
2274 - //update video time
2275 - updateVideoTime:function(start_ntp, end_ntp){
2276 - //update media
2277 - this.media_element.updateSourceTimes( start_ntp, end_ntp );
2278 - //update mv_time
2279 - this.setStatus(start_ntp+'/'+end_ntp);
2280 - //reset slider
2281 - this.setSliderValue(0);
2282 - //reset seek_offset:
2283 - if(this.media_element.selected_source.supports_url_time_encoding)
2284 - this.seek_time_sec=0;
2285 - else
2286 - this.seek_time_sec=ntp2seconds(start_ntp);
2287 - },
2288 - //@@todo overwite by embed library if we can render frames natavily
2289 - renderTimelineThumbnail:function( options ){
2290 - var my_thumb_src = this.media_element.getThumbnailURL();
2291 -
2292 - if( my_thumb_src.indexOf('t=') !== -1){
2293 - var time_ntp = seconds2ntp ( options.time + parseInt(this.start_offset) );
2294 - my_thumb_src = getUpdateTimeURL( my_thumb_src, time_ntp, options.size );
2295 - }
2296 - var thumb_class = (typeof options['thumb_class'] !='undefined')? options['thumb_class'] : '';
2297 - return '<div class="' + thumb_class + '" src="' + my_thumb_src +'" '+
2298 - 'style="height:' + options.height + 'px;' +
2299 - 'width:' + options.width + 'px" >' +
2300 - '<img src="' + my_thumb_src +'" '+
2301 - 'style="height:' + options.height + 'px;' +
2302 - 'width:' + options.width + 'px">' +
2303 - '</div>';
2304 - },
2305 - updateThumbTimeNTP:function( time){
2306 - this.updateThumbTime( ntp2seconds(time) - parseInt(this.start_offset) );
2307 - },
2308 - updateThumbTime:function( float_sec ){
2309 - //js_log('updateThumbTime:'+float_sec);
2310 - var _this = this;
2311 - if( typeof this.org_thum_src=='undefined' ){
2312 - this.org_thum_src = this.media_element.getThumbnailURL();
2313 - }
2314 - if( this.org_thum_src.indexOf('t=') !== -1){
2315 - this.last_thumb_url = getUpdateTimeURL(this.org_thum_src,seconds2ntp( float_sec + parseInt(this.start_offset)));
2316 - if(!this.thumbnail_updating){
2317 - this.updateThumbnail(this.last_thumb_url ,false);
2318 - this.last_thumb_url =null;
2319 - }
2320 - }
2321 - },
2322 - //for now provide a src url .. but need to figure out how to copy frames from video for plug-in based thumbs
2323 - updateThumbPerc:function( perc ){
2324 - return this.updateThumbTime( (this.getDuration() * perc) );
2325 - },
2326 - //updates the thumbnail if the thumbnail is being displayed
2327 - updateThumbnail : function(src, quick_switch){
2328 - js_log('update thumb: ' + src);
2329 - //make sure we don't go to the same url if we are not already updating:
2330 - if( !this.thumbnail_updating && $j('#img_thumb_'+this.id).attr('src')== src )
2331 - return false;
2332 - //if we are updating don't re-go to the updating url:
2333 - if(this.thumbnail_updating && $j('#new_img_thumb_'+this.id).attr('src')== src )
2334 - return false;
2335 -
2336 - if(quick_switch){
2337 - $j('#img_thumb_'+this.id).attr('src', src);
2338 - }else{
2339 - var _this = this;
2340 - //if still animating remove new_img_thumb_
2341 - if(this.thumbnail_updating==true)
2342 - $j('#new_img_thumb_'+this.id).stop().remove();
2343 -
2344 - if(this.thumbnail_disp){
2345 - js_log('set to thumb:'+ src);
2346 - this.thumbnail_updating=true;
2347 - $j('#dc_'+this.id).append('<img src="'+src+'" ' +
2348 - 'style="display:none;position:absolute;zindex:2;top:0px;left:0px;" ' +
2349 - 'width="'+this.width+'" height="'+this.height+'" '+
2350 - 'id = "new_img_thumb_'+this.id+'" />');
2351 - //js_log('appended: new_img_thumb_');
2352 - $j('#new_img_thumb_'+this.id).fadeIn("slow", function(){
2353 - //once faded in remove org and rename new:
2354 - $j('#img_thumb_'+_this.id).remove();
2355 - $j('#new_img_thumb_'+_this.id).attr('id', 'img_thumb_'+_this.id);
2356 - $j('#img_thumb_'+_this.id).css('zindex','1');
2357 - _this.thumbnail_updating=false;
2358 - //js_log("done fadding in "+ $j('#img_thumb_'+_this.id).attr("src"));
2359 -
2360 - //if we have a thumb queued update to that
2361 - if(_this.last_thumb_url){
2362 - var src_url =_this.last_thumb_url;
2363 - _this.last_thumb_url=null;
2364 - _this.updateThumbnail(src_url);
2365 - }
2366 - });
2367 - }
2368 - }
2369 - },
2370 - /** Returns the HTML code for the video when it is in thumbnail mode.
2371 - This includes the specified thumbnail as well as buttons for
2372 - playing, configuring the player, inline cmml display, HTML linkback,
2373 - download, and embed code.
2374 - */
2375 - getThumbnailHTML : function ()
2376 - {
2377 - var thumb_html = '';
2378 - var class_atr='';
2379 - var style_atr='';
2380 - //if(this.class)class_atr = ' class="'+this.class+'"';
2381 - //if(this.style)style_atr = ' style="'+this.style+'"';
2382 - // else style_atr = 'overflow:hidden;height:'+this.height+'px;width:'+this.width+'px;';
2383 - this.thumbnail = this.media_element.getThumbnailURL();
2384 -
2385 - //put it all in the div container dc_id
2386 - thumb_html+= '<div id="dc_'+this.id+'" style="position:relative;'+
2387 - ' overflow:hidden; top:0px; left:0px; width:'+this.playerPixelWidth()+'px; height:'+this.playerPixelHeight()+'px; z-index:0;">'+
2388 - '<img width="'+this.playerPixelWidth()+'" height="'+this.playerPixelHeight()+'" style="position:relative;width:'+this.playerPixelWidth()+';height:'+this.playerPixelHeight()+'"' +
2389 - ' id="img_thumb_'+this.id+'" src="' + this.thumbnail + '">';
2390 -
2391 - if(this.play_button==true)
2392 - thumb_html+=this.getPlayButton();
2393 -
2394 - thumb_html+='</div>';
2395 - return thumb_html;
2396 - },
2397 - getEmbeddingHTML:function()
2398 - {
2399 - var thumbnail = this.media_element.getThumbnailURL();
2400 -
2401 - var embed_thumb_html;
2402 - if(thumbnail.substring(0,1)=='/'){
2403 - eURL = parseUri(mv_embed_path);
2404 - embed_thumb_html = eURL.protocol + '://' + eURL.host + thumbnail;
2405 - //js_log('set from mv_embed_path:'+embed_thumb_html);
2406 - }else{
2407 - embed_thumb_html = (thumbnail.indexOf('http://')!=-1)?thumbnail:mv_embed_path + thumbnail;
2408 - }
2409 - var embed_code_html = '&lt;script type=&quot;text/javascript&quot; ' +
2410 - 'src=&quot;'+mv_embed_path+'mv_embed.js&quot;&gt;&lt;/script&gt' +
2411 - '&lt;video ';
2412 - if(this.roe){
2413 - embed_code_html+='roe=&quot;'+this.roe+'&quot; &gt;';
2414 - }else{
2415 - embed_code_html+='src=&quot;'+this.src+'&quot; ' +
2416 - 'thumbnail=&quot;'+embed_thumb_html+'&quot;&gt;';
2417 - }
2418 - //close the video tag
2419 - embed_code_html+='&lt;/video&gt;';
2420 -
2421 - return embed_code_html;
2422 - },
2423 - doOptionsHTML:function()
2424 - {
2425 - var sel_id = (this.pc!=null)?this.pc.pp.id:this.id;
2426 - var pos = $j('#options_button_'+sel_id).offset();
2427 - pos['top']=pos['top']+24;
2428 - pos['left']=pos['left']-124;
2429 - //js_log('pos of options button: t:'+pos['top']+' l:'+ pos['left']);
2430 - $j('#mv_embedded_options_'+sel_id).css(pos).toggle();
2431 - return;
2432 - },
2433 - getPlayButton:function(id){
2434 - if(!id)id=this.id;
2435 - return '<div id="big_play_link_'+id+'" class="large_play_button" '+
2436 - 'style="left:'+((this.playerPixelWidth()-130)/2)+'px;'+
2437 - 'top:'+((this.playerPixelHeight()-96)/2)+'px;"></div>';
2438 - },
2439 - //display the code to remotely embed this video:
2440 - showEmbedCode : function(embed_code){
2441 - if(!embed_code)
2442 - embed_code = this.getEmbeddingHTML();
2443 - var o='';
2444 - if(this.linkback){
2445 - o+='<a class="email" href="'+this.linkback+'">Share Clip via Link</a> '+
2446 - '<p>or</p> ';
2447 - }
2448 - o+='<span style="color:#FFF;font-size:14px;">Embed Clip in Blog or Site</span>'+
2449 - '<div class="embed_code"> '+
2450 - '<textarea onClick="this.select();" id="embedding_user_html_'+this.id+'" name="embed">' +
2451 - embed_code+
2452 - '</textarea> '+
2453 - '<button onClick="$j(\'#'+this.id+'\').get(0).copyText(); return false;" class="copy_to_clipboard">Copy to Clipboard</button> '+
2454 - '</div> '+
2455 - '</div>';
2456 - this.displayHTML(o);
2457 - },
2458 - copyText:function(){
2459 - $j('#embedding_user_html_'+this.id).focus().select();
2460 - if(document.selection){
2461 - CopiedTxt = document.selection.createRange();
2462 - CopiedTxt.execCommand("Copy");
2463 - }
2464 - },
2465 - showTextInterface:function(){
2466 - var _this = this;
2467 - //display the text container with loading text:
2468 - //@@todo support position config
2469 - var loc = $j(this).position();
2470 - if($j('#metaBox_'+this.id).length==0){
2471 - $j(this).after('<div style="position:absolute;z-index:10;'+
2472 - 'top:' + (loc.top) + 'px;' +
2473 - 'left:' + (parseInt( loc.left ) + parseInt(this.width) + 10 )+'px;' +
2474 - 'height:'+ parseInt( this.height )+'px;width:400px;' +
2475 - 'background:white;border:solid black;' +
2476 - 'display:none;" ' +
2477 - 'id="metaBox_' + this.id + '">'+
2478 - getMsg('loading_txt') +
2479 - '</div>');
2480 - }
2481 - //fade in the text display
2482 - $j('#metaBox_'+this.id).fadeIn("fast");
2483 - //check if textObj present:
2484 - if(typeof this.textInterface == 'undefined' ){
2485 - //load the default text interface:
2486 - mvJsLoader.doLoad({
2487 - 'textInterface':'libTimedText/mv_timed_text.js',
2488 - '$j.fn.hoverIntent':'jquery/plugins/jquery.hoverIntent.js'
2489 - }, function(){
2490 -
2491 - _this.textInterface = new textInterface( _this );
2492 - //show interface
2493 - _this.textInterface.show();
2494 - js_log("NEW TEXT INTERFACE");
2495 - for(var i in _this.textInterface.availableTracks){
2496 - js_log("tracks in new interface: "+_this.id+ ' tid:' + i);
2497 - }
2498 - }
2499 - );
2500 - }else{
2501 - //show interface
2502 - this.textInterface.show();
2503 - }
2504 - },
2505 - closeTextInterface:function(){
2506 - js_log('closeTextInterface '+ typeof this.textInterface);
2507 - if(typeof this.textInterface !== 'undefined' ){
2508 - this.textInterface.close();
2509 - }
2510 - },
2511 - /** Generic function to display custom HTML inside the mv_embed element.
2512 - The code should call the closeDisplayedHTML function to close the
2513 - display of the custom HTML and restore the regular mv_embed display.
2514 - @param {String} HTML code for the selection list.
2515 - */
2516 - displayHTML:function(html_code)
2517 - {
2518 - var sel_id = (this.pc!=null)?this.pc.pp.id:this.id;
2519 -
2520 - if(!this.supports['overlays'])
2521 - this.stop();
2522 -
2523 - //put select list on-top
2524 - //make sure the parent is relatively positioned:
2525 - $j('#'+sel_id).css('position', 'relative');
2526 - //set height width (check for playlist container)
2527 - var width = (this.pc)?this.pc.pp.width:this.playerPixelWidth();
2528 - var height = (this.pc)?this.pc.pp.height:this.playerPixelHeight();
2529 -
2530 - if(this.pc)
2531 - height+=(this.pc.pp.pl_layout.title_bar_height + this.pc.pp.pl_layout.control_height);
2532 -
2533 - var fade_in = true;
2534 - if($j('#blackbg_'+sel_id).length!=0)
2535 - {
2536 - fade_in = false;
2537 - $j('#blackbg_'+sel_id).remove();
2538 - }
2539 - //fade in a black bg div ontop of everything
2540 - var div_code = '<div id="blackbg_'+sel_id+'" class="videoComplete" ' +
2541 - 'style="height:'+parseInt(height)+'px;width:'+parseInt(width)+'px;">'+
2542 -// '<span class="displayHTML" id="con_vl_'+this.id+'" style="position:absolute;top:20px;left:20px;color:white;">' +
2543 - '<div class="videoOptionsComplete">'+
2544 - //@@TODO: this style should go to .css
2545 - '<span style="float:right;margin-right:10px">' +
2546 - '<a href="#" style="color:white;" onClick="$j(\'#'+sel_id+'\').get(0).closeDisplayedHTML();return false;">close</a>' +
2547 - '</span>'+
2548 - '<div id="mv_disp_inner_'+sel_id+'" style="padding-top:10px;">'+
2549 - html_code
2550 - +'</div>'+
2551 -// close_link+'</span>'+
2552 - '</div></div>';
2553 - $j('#'+sel_id).prepend(div_code);
2554 - if (fade_in)
2555 - $j('#blackbg_'+sel_id).fadeIn("slow");
2556 - else
2557 - $j('#blackbg_'+sel_id).show();
2558 - return false; //onclick action return false
2559 - },
2560 - /** Close the custom HTML displayed using displayHTML and restores the
2561 - regular mv_embed display.
2562 - */
2563 - closeDisplayedHTML:function(){
2564 - var sel_id = (this.pc!=null)?this.pc.pp.id:this.id;
2565 - $j('#blackbg_'+sel_id).fadeOut("slow", function(){
2566 - $j('#blackbg_'+sel_id).remove();
2567 - });
2568 - return false;//onclick action return false
2569 - },
2570 - selectPlaybackMethod:function(){
2571 - //get id (in case where we have a parent container)
2572 - var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
2573 -
2574 - var _this=this;
2575 - var out='<span style="color:#FFF;background-color:black;"><blockquote>';
2576 - var _this=this;
2577 - //js_log('selected src'+ _this.media_element.selected_source.url);
2578 - $j.each(this.media_element.getPlayableSources(), function(index, source)
2579 - {
2580 - var default_player = embedTypes.players.defaultPlayer( source.getMIMEType() );
2581 - var source_select_code = '$j(\'#'+this_id+'\').get(0).closeDisplayedHTML(); $j(\'#'+_this.id+'\').get(0).media_element.selectSource(\''+index+'\');';
2582 -
2583 - //var player_code = _this.getPlayerSelectList( source.getMIMEType(), index, source_select_code);
2584 -
2585 - var is_selected = (source == _this.media_element.selected_source);
2586 - var image_src = mv_embed_path+'images/stream/';
2587 - if( source.mime_type == 'video/x-flv' ){
2588 - image_src += 'flash_icon_';
2589 - }else if( source.mime_type == 'video/h264'){
2590 - //for now all mp4 content is pulled from archive.org (so use archive.org icon)
2591 - image_src += 'archive_org_';
2592 - }else{
2593 - image_src += 'fish_xiph_org_';
2594 - }
2595 - image_src += is_selected ? 'color':'bw';
2596 - image_src += '.png';
2597 - if (default_player)
2598 - {
2599 - out += '<img src="'+image_src+'"/>';
2600 - if( ! is_selected )
2601 - out+='<a href="#" onClick="' + source_select_code + 'embedTypes.players.userSelectPlayer(\''+default_player.id+'\',\''+source.getMIMEType()+'\'); return false;">';
2602 - out += source.getTitle()+ (is_selected?'</a>':'') + ' ';
2603 - //output the player select code:
2604 - var supporting_players = embedTypes.players.getMIMETypePlayers( source.getMIMEType() );
2605 - out+='<div id="player_select_list_' + index + '" class="player_select_list"><ul>';
2606 - for(var i=0; i < supporting_players.length ; i++){
2607 - if( _this.selected_player.id == supporting_players[i].id && is_selected ){
2608 - out+='<li style="border-style:dashed;margin-left:20px;">'+
2609 - '<img border="0" width="16" height="16" src="'+mv_embed_path+'images/plugin.png">'+
2610 - supporting_players[i].getName() +
2611 - '</li>';
2612 - }else{
2613 - //else gray plugin and the plugin with link to select
2614 - out+='<li style="margin-left:20px;">'+
2615 - '<a href="#" onClick="'+ source_select_code + 'embedTypes.players.userSelectPlayer(\''+supporting_players[i].id+'\',\''+ source.getMIMEType()+'\');return false;">'+
2616 - '<img border="0" width="16" height="16" src="'+mv_embed_path+'images/plugin_disabled.png">'+
2617 - supporting_players[i].getName() +
2618 - '</a>'+
2619 - '</li>';
2620 - }
2621 - }
2622 - out+='</ul></div>';
2623 - }else
2624 - out+= source.getTitle() + ' - no player available';
2625 - });
2626 - out+='</blockquote></span>';
2627 - this.displayHTML(out);
2628 - },
2629 - /*download list is exessivly complicated ... rewrite for clarity: */
2630 - showVideoDownload:function(){
2631 - //load the roe if avaliable (to populate out download options:
2632 - js_log('f:showVideoDownload '+ this.roe + ' ' + this.media_element.addedROEData);
2633 - if(this.roe && this.media_element.addedROEData==false){
2634 - var _this = this;
2635 - this.displayHTML(getMsg('loading_txt'));
2636 - do_request(this.roe, function(data)
2637 - {
2638 - _this.media_element.addROE(data);
2639 - $j('#mv_disp_inner_'+_this.id).html(_this.getShowVideoDownload());
2640 - });
2641 - }else{
2642 - this.displayHTML(this.getShowVideoDownload());
2643 - }
2644 - },
2645 - getShowVideoDownload:function(){
2646 - var out='<b style="color:white;">'+getMsg('download_segment')+'</b><br>';
2647 - out+='<span style="color:white"><blockquote>';
2648 - var dl_list='';
2649 - var dl_txt_list='';
2650 -
2651 - $j.each(this.media_element.getSources(), function(index, source){
2652 - var dl_line = '<li>' + '<a style="color:white" href="' + source.getURI() +'"> '
2653 - + source.getTitle()+'</a> '+ '</li>'+"\n";
2654 - if( source.getURI().indexOf('?t=')!==-1){
2655 - out+=dl_line;
2656 - }else if(this.getMIMEType()=="text/cmml"){
2657 - dl_txt_list+=dl_line;
2658 - }else{
2659 - dl_list+=dl_line;
2660 - }
2661 - });
2662 - if(dl_list!='')
2663 - out+='</blockquote>'+getMsg('download_full')+"<blockquote>"+dl_list+'</blockquote>';
2664 - if(dl_txt_list!='')
2665 - out+='</blockquote>'+getMsg('download_text')+"<blockquote>"+dl_txt_list+'</blockquote></span>';
2666 - return out;
2667 - },
2668 - /*
2669 - * base embed controls
2670 - * the play button calls
2671 - */
2672 - play:function(){
2673 - var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
2674 - js_log( "mv_embed play:" + this.id);
2675 - js_log('thum disp:'+this.thumbnail_disp);
2676 - //check if thumbnail is being displayed and embed html
2677 - if( this.thumbnail_disp ){
2678 - if( !this.selected_player ){
2679 - js_log('no selected_player');
2680 - //this.innerHTML = this.getPluginMissingHTML();
2681 - //$j(this).html(this.getPluginMissingHTML());
2682 - $j('#'+this.id).html( this.getPluginMissingHTML() );
2683 - }else{
2684 - this.doEmbedHTML();
2685 - this.onClipDone_disp=false;
2686 - this.paused=false;
2687 - this.thumbnail_disp=false;
2688 - }
2689 - }else{
2690 - //the plugin is already being displayed
2691 - this.paused=false; //make sure we are not "paused"
2692 - }
2693 - $j("#mv_play_pause_button_" + this_id).attr({
2694 - 'class':'pause_button'
2695 - }).unbind( "click" ).click(function(){
2696 - $j('#' + this_id ).get(0).pause();
2697 - });
2698 - },
2699 - /*
2700 - * base embed pause
2701 - * there is no general way to pause the video
2702 - * must be overwritten by embed object to support this functionality.
2703 - */
2704 - pause: function(){
2705 - var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
2706 - js_log('mv_embed:do pause');
2707 - //(playing) do pause
2708 - this.paused=true;
2709 - //update the ctrl "paused state"
2710 - $j("#mv_play_pause_button_" + this_id).attr({
2711 - 'class':'play_button'
2712 - }).unbind( "click" ).click(function(){
2713 - $j('#'+this_id).get(0).play();
2714 - });
2715 - },
2716 - /*
2717 - * base embed stop (can be overwritten by the plugin)
2718 - */
2719 - stop: function(){
2720 - var _this = this;
2721 - js_log('mvEmbed:stop:'+this.id);
2722 - //first issue pause to update interface (only call the parent)
2723 - if(this['parent_pause']){
2724 - this.parent_pause();
2725 - }else{
2726 - this.pause();
2727 - }
2728 - //reset the currentTime:
2729 - this.currentTime=0;
2730 - //check if thumbnail is being displayed in which case do nothing
2731 - if(this.thumbnail_disp){
2732 - //already in stooped state
2733 - js_log('already in stopped state');
2734 - }else{
2735 - //rewrite the html to thumbnail disp
2736 - this.doThumbnailHTML();
2737 - this.bufferedPercent=0; //reset buffer state
2738 - this.setSliderValue(0);
2739 - this.setStatus( this.getTimeReq() );
2740 - }
2741 - //make sure the big playbutton is has click action:
2742 - $j('#big_play_link_' + _this.id).unbind('click').click(function(){
2743 - $j('#' +_this.id).get(0).play();
2744 - });
2745 -
2746 - if(this.update_interval)
2747 - {
2748 - clearInterval(this.update_interval);
2749 - this.update_interval = null;
2750 - }
2751 - },
2752 - toggleMute:function(){
2753 - var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
2754 - js_log('f:toggleMute');
2755 - if(this.muted){
2756 - this.muted=false;
2757 - $j('#volume_icon_'+this_id).removeClass('volume_off').addClass('volume_on');
2758 - }else{
2759 - this.muted=true;
2760 - $j('#volume_icon_'+this_id).removeClass('volume_on').addClass('volume_off');
2761 - }
2762 - },
2763 - fullscreen:function(){
2764 - js_log('fullscreen not supported for this plugin type');
2765 - },
2766 - /* returns bool true if playing or paused, false if stooped
2767 - */
2768 - isPlaying : function(){
2769 - if(this.thumbnail_disp){
2770 - //in stoped state
2771 - return false;
2772 - }else if( this.paused ){
2773 - //paused state
2774 - return false;
2775 - }else{
2776 - return true;
2777 - }
2778 - },
2779 - isPaused : function(){
2780 - return this.isPlaying() && this.paused;
2781 - },
2782 - isStoped : function(){
2783 - return this.thumbnail_disp;
2784 - },
2785 - playlistSupport:function(){
2786 - //by default not supported (implemented in js)
2787 - return false;
2788 - },
2789 - postEmbedJS:function(){
2790 - return '';
2791 - },
2792 - getPluginEmbed : function(){
2793 - if (window.document[this.pid]){
2794 - return window.document[this.pid];
2795 - }
2796 - if (embedTypes.msie){
2797 - return document.getElementById(this.pid );
2798 - }else{
2799 - if (document.embeds && document.embeds[this.pid])
2800 - return document.embeds[this.pid];
2801 - }
2802 - return null;
2803 - },
2804 - //HELPER Functions for selected source
2805 - /*
2806 - * returns the selected source url for players to play
2807 - */
2808 - getURI : function(seek_time_sec){
2809 - return this.media_element.selected_source.getURI( this.seek_time_sec );
2810 - },
2811 - supportsURLTimeEncoding: function(){
2812 - return this.media_element.selected_source.supports_url_time_encoding;
2813 - },
2814 - setSliderValue: function(perc, hide_progress){
2815 -
2816 - //js_log('setSliderValue:'+perc+' ct:'+ this.currentTime);
2817 - var this_id = (this.pc)?this.pc.pp.id:this.id;
2818 - //alinment offset:
2819 - if(!this.mv_seeker_width)
2820 - this.mv_seeker_width = $j('#mv_seeker_slider_'+this_id).width();
2821 -
2822 - var val = Math.round( perc * $j('#mv_seeker_'+this_id).width() - (this.mv_seeker_width*perc));
2823 - if(val > ($j('#mv_seeker_'+this_id).width() -this.mv_seeker_width) )
2824 - val = $j('#mv_seeker_'+this_id).width() -this.mv_seeker_width ;
2825 - $j('#mv_seeker_slider_'+this_id).css('left', (val)+'px' );
2826 -
2827 - //update the playback progress bar
2828 - if( ! hide_progress ){
2829 - $j('#mv_seeker_' + this_id + ' .mv_playback').css("width", Math.round( val + (this.mv_seeker_width*.5) ) + 'px' );
2830 - }else{
2831 - //hide the progress bar
2832 - $j('#mv_seeker_' + this_id + ' .mv_playback').css("width", "0px");
2833 - }
2834 -
2835 - //update the buffer progress bar (if available )
2836 - if( this.bufferedPercent!=0 ){
2837 - //js_log('bufferedPercent: ' + this.bufferedPercent);
2838 - if(this.bufferedPercent > 1)
2839 - this.bufferedPercent=1;
2840 - $j('#mv_seeker_' + this_id + ' .mv_buffer').css("width", (this.bufferedPercent*100) +'%' );
2841 - }else{
2842 - $j('#mv_seeker_' + this_id + ' .mv_buffer').css("width", '0px' );
2843 - }
2844 -
2845 - //js_log('set#mv_seeker_slider_'+this_id + ' perc in: ' + perc + ' * ' + $j('#mv_seeker_'+this_id).width() + ' = set to: '+ val + ' - '+ Math.round(this.mv_seeker_width*perc) );
2846 - //js_log('op:' + offset_perc + ' *('+perc+' * ' + $j('#slider_'+id).width() + ')');
2847 - },
2848 - highlightPlaySection:function(options){
2849 - js_log('highlightPlaySection');
2850 - var this_id = (this.pc)?this.pc.pp.id:this.id;
2851 - var dur = this.getDuration();
2852 - var hide_progress = true;
2853 - //set the left percet and update the slider:
2854 - rel_start_sec = ( ntp2seconds( options['start']) - this.start_offset );
2855 -
2856 - var slider_perc=0;
2857 - if( rel_start_sec <= 0 ){
2858 - left_perc =0;
2859 - options['start'] = seconds2ntp( this.start_offset );
2860 - rel_start_sec=0;
2861 - this.setSliderValue( 0 , hide_progress);
2862 - }else{
2863 - left_perc = parseInt( (rel_start_sec / dur)*100 ) ;
2864 - slider_perc = (left_perc / 100);
2865 - }
2866 - if( ! this.isPlaying() ){
2867 - this.setSliderValue( slider_perc , hide_progress);
2868 - }
2869 -
2870 - width_perc = parseInt( (( ntp2seconds( options['end'] ) - ntp2seconds( options['start'] ) ) / dur)*100 ) ;
2871 - if( (width_perc + left_perc) > 100 ){
2872 - width_perc = 100 - left_perc;
2873 - }
2874 - //js_log('should hl: '+rel_start_sec+ '/' + dur + ' re:' + rel_end_sec+' lp:' + left_perc + ' width: ' + width_perc);
2875 - $j('#mv_seeker_' + this_id + ' .mv_highlight').css({
2876 - 'left':left_perc+'%',
2877 - 'width':width_perc+'%'
2878 - }).show();
2879 -
2880 - this.jump_time = options['start'];
2881 - this.seek_time_sec = ntp2seconds( options['start']);
2882 - //trim output to
2883 - this.setStatus( getMsg('seek_to')+' '+ seconds2ntp( this.seek_time_sec ) );
2884 - js_log('DO update: ' + this.jump_time);
2885 - this.updateThumbTime( rel_start_sec );
2886 - },
2887 - hideHighlight:function(){
2888 - var this_id = (this.pc)?this.pc.pp.id:this.id;
2889 - $j('#mv_seeker_' + this_id + ' .mv_highlight').hide();
2890 - this.setStatus( this.getTimeReq() );
2891 - this.setSliderValue( 0 );
2892 - },
2893 - setStatus:function(value){
2894 - var id = (this.pc)?this.pc.pp.id:this.id;
2895 - //update status:
2896 - $j('#mv_time_'+id).html(value);
2897 - }
2898 -}
28991700 /*
29001701 * utility functions:
29011702 */
@@ -2997,7 +1798,7 @@
29981799 loadExternalJs( req_url );
29991800 }
30001801 }
3001 -//do a "normal" request (should be deprecated via extending the mediaWiki API)
 1802+//do a "normal" request (should be depriecated via extending the mediaWiki API)
30021803 function do_request(req_url, callback){
30031804 //pass along a unique inentifier if set
30041805 js_log('do request: ' + req_url);
@@ -3067,13 +1868,13 @@
30681869 //load external js via dom injection
30691870 //@@todo swich over to jQuery injection
30701871 function loadExternalJs(url, callback){
3071 - //add a unquie request id to ensure fresh copies where appopriate
 1872+ //add a unique request id to ensure fresh copies where appropriate
30721873 if( url.indexOf('?')==-1 ){
30731874 url+='?'+mv_embed_urid;
30741875 }
30751876 js_log('load js: '+ url);
30761877 //if(window['$j'])
3077 - //have to use direct ajax call insted of $j.getScript()
 1878+ //have to use direct ajax call instead of $j.getScript()
30781879 //since you can't send "cache" option to $j.getScript()
30791880 /*$j.ajax({
30801881 type: "GET",
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libEmbedObj/mv_baseEmbed.js
@@ -0,0 +1,1214 @@
 2+/** base embedVideo object
 3+ @param element <video> tag used for initialization.
 4+ @constructor
 5+*/
 6+
 7+var embedVideo = function(element) {
 8+ return this.init(element);
 9+};
 10+
 11+embedVideo.prototype = {
 12+ /** The mediaElement object containing all mediaSource objects */
 13+ media_element:null,
 14+ preview_mode:false,
 15+ slider:null,
 16+ ready_to_play:false, //should use html5 ready state
 17+ load_error:false, //used to set error in case of error
 18+ loading_external_data:false,
 19+ thumbnail_updating:false,
 20+ thumbnail_disp:true,
 21+ init_with_sources_loadedDone:false,
 22+ inDOM:false,
 23+ //for onClip done stuff:
 24+ anno_data_cache:null,
 25+ seek_time_sec:0,
 26+ base_seeker_slider_offset:null,
 27+ onClipDone_disp:false,
 28+ supports:{},
 29+ //for seek thumb updates:
 30+ cur_thumb_seek_time:0,
 31+ thumb_seek_interval:null,
 32+ //set the buffered percent:
 33+ bufferedPercent:0,
 34+ //utility functions for property values:
 35+ hx : function ( s ) {
 36+ if ( typeof s != 'String' ) {
 37+ s = s.toString();
 38+ }
 39+ return s.replace( /&/g, '&amp;' )
 40+ . replace( /</g, '&lt;' )
 41+ . replace( />/g, '&gt;' );
 42+ },
 43+ hq : function ( s ) {
 44+ return '"' + this.hx( s ) + '"';
 45+ },
 46+ playerPixelWidth : function()
 47+ {
 48+ var player = $j('#mv_embedded_player_'+this.id).get(0);
 49+ if(typeof player!='undefined' && player['offsetWidth'])
 50+ return player.offsetWidth;
 51+ else
 52+ return parseInt(this.width);
 53+ },
 54+ playerPixelHeight : function()
 55+ {
 56+ var player = $j('#mv_embedded_player_'+this.id).get(0);
 57+ if(typeof player!='undefined' && player['offsetHeight'])
 58+ return player.offsetHeight;
 59+ else
 60+ return parseInt(this.height);
 61+ },
 62+ init: function(element){
 63+ //this.element_pointer = element;
 64+
 65+ //inherit all the default video_attributes
 66+ for(var attr in default_video_attributes){ //for in loop oky on user object
 67+ if(element.getAttribute(attr)){
 68+ this[attr]=element.getAttribute(attr);
 69+ //js_log('attr:' + attr + ' val: ' + video_attributes[attr] +" "+'elm_val:' + element.getAttribute(attr) + "\n (set by elm)");
 70+ }else{
 71+ this[attr]=default_video_attributes[attr];
 72+ //js_log('attr:' + attr + ' val: ' + video_attributes[attr] +" "+ 'elm_val:' + element.getAttribute(attr) + "\n (set by attr)");
 73+ }
 74+ }
 75+ if( this.duration!=null && this.duration.split(':').length >= 2)
 76+ this.duration = ntp2seconds( this.duration );
 77+
 78+ //if style is set override width and height
 79+ var dwh = mv_default_video_size.split('x');
 80+ this.width = element.style.width ? element.style.width : dwh[0];
 81+ this.height = element.style.height ? element.style.height : dwh[1];
 82+ //set the plugin id
 83+ this.pid = 'pid_' + this.id;
 84+
 85+ //grab any innerHTML and set it to missing_plugin_html
 86+ //@@todo we should strip source tags instead of checking and skipping
 87+ if(element.innerHTML!='' && element.getElementsByTagName('source').length==0){
 88+ js_log('innerHTML: ' + element.innerHTML);
 89+ this.user_missing_plugin_html=element.innerHTML;
 90+ }
 91+ // load all of the specified sources
 92+ this.media_element = new mediaElement(element);
 93+ },
 94+ on_dom_swap: function(){
 95+ js_log('f:on_dom_swap');
 96+ // Process the provided ROE file... if we don't yet have sources
 97+ if(this.roe && this.media_element.sources.length==0 ){
 98+ js_log('loading external data');
 99+ this.loading_external_data=true;
 100+ var _this = this;
 101+ do_request(this.roe, function(data)
 102+ {
 103+ //continue
 104+ _this.media_element.addROE(data);
 105+ js_log('added_roe::' + _this.media_element.sources.length);
 106+
 107+ js_log('set loading_external_data=false');
 108+ _this.loading_external_data=false;
 109+
 110+ _this.init_with_sources_loaded();
 111+ });
 112+ }
 113+ },
 114+ init_with_sources_loaded : function()
 115+ {
 116+ js_log('f:init_with_sources_loaded');
 117+ //set flag that we have run this function:
 118+ this.init_with_sources_loadedDone=true;
 119+ //autoseletct the source
 120+ this.media_element.autoSelectSource();
 121+ //auto select player based on prefrence or default order
 122+ if( !this.media_element.selected_source )
 123+ {
 124+ //check for parent clip:
 125+ if( typeof this.pc != 'undefined' ){
 126+ js_log('no sources, type:' +this.type + ' check for html');
 127+ //do load player if just displaying innerHTML:
 128+ if(this.pc.type =='text/html'){
 129+ this.selected_player = embedTypes.players.defaultPlayer( 'text/html' );
 130+ js_log('set selected player:'+ this.selected_player.mime_type);
 131+ }
 132+ }
 133+ }else{
 134+ this.selected_player = embedTypes.players.defaultPlayer( this.media_element.selected_source.mime_type );
 135+ }
 136+ if( this.selected_player ){
 137+ js_log('selected ' + this.selected_player.getName());
 138+ js_log("PLAYBACK TYPE: "+this.selected_player.library);
 139+ this.thumbnail_disp = true;
 140+ this.inheritEmbedObj();
 141+ }else{
 142+ //no source's playable
 143+ var missing_type ='';
 144+ var or ='';
 145+ for( var i=0; i < this.media_element.sources.length; i++){
 146+ missing_type+=or + this.media_element.sources[i].mime_type;
 147+ or=' or ';
 148+ }
 149+ if( this.pc )
 150+ var missing_type = this.pc.type;
 151+
 152+ js_log('no player found for given source type ' + missing_type);
 153+ this.load_error= gM('generic_missing_plugin', missing_type );
 154+ }
 155+ },
 156+ inheritEmbedObj:function(){
 157+ //@@note: tricky cuz direct overwrite is not so ideal.. since the extended object is already tied to the dom
 158+ //clear out any non-base embedObj stuff:
 159+ if(this.instanceOf){
 160+ eval('tmpObj = '+this.instanceOf);
 161+ for(var i in tmpObj){ //for in loop oky for object
 162+ if(this['parent_'+i]){
 163+ this[i]=this['parent_'+i];
 164+ }else{
 165+ this[i]=null;
 166+ }
 167+ }
 168+ }
 169+ //set up the new embedObj
 170+ js_log('f: inheritEmbedObj: embedding with ' + this.selected_player.library);
 171+ var _this = this;
 172+ this.selected_player.load( function()
 173+ {
 174+ //js_log('inheriting '+_this.selected_player.library +'Embed to ' + _this.id + ' ' + $j('#'+_this.id).length);
 175+ //var _this = $j('#'+_this.id).get(0);
 176+ //js_log( 'type of ' + _this.selected_player.library +'Embed + ' +
 177+ // eval('typeof '+_this.selected_player.library +'Embed'));
 178+ eval('embedObj = ' +_this.selected_player.library +'Embed;');
 179+ for(var method in embedObj){ //for in loop oky for object
 180+ //parent method preservation for local overwritten methods
 181+ if(_this[method])
 182+ _this['parent_' + method] = _this[method];
 183+ _this[method]=embedObj[method];
 184+ }
 185+ js_log('TYPEOF_ppause: ' + typeof _this['parent_pause']);
 186+
 187+ if(_this.inheritEmbedOverride){
 188+ _this.inheritEmbedOverride();
 189+ }
 190+ //update controls if possible
 191+ if(!_this.loading_external_data)
 192+ _this.refreshControlsHTML();
 193+
 194+ //js_log("READY TO PLAY:"+_this.id);
 195+ _this.ready_to_play=true;
 196+ _this.getDuration();
 197+ _this.getHTML();
 198+ });
 199+ },
 200+ selectPlayer:function(player)
 201+ {
 202+ var _this = this;
 203+ if(this.selected_player.id != player.id){
 204+ this.selected_player = player;
 205+ this.inheritEmbedObj();
 206+ }
 207+ },
 208+ getTimeReq:function(){
 209+ js_log('f:getTimeReq:'+ this.getDurationNTP());
 210+ var default_time_req = '0:00:00/' + this.getDurationNTP() ;
 211+ if(!this.media_element)
 212+ return default_time_req;
 213+ if(!this.media_element.selected_source)
 214+ return default_time_req;
 215+ if(!this.media_element.selected_source.end_ntp)
 216+ return default_time_req;
 217+ return this.media_element.selected_source.start_ntp+'/'+this.media_element.selected_source.end_ntp;
 218+ },
 219+ getDuration:function(){
 220+ //update some local pointers for the selected source:
 221+ if( this.media_element.selected_source.duration &&
 222+ this.media_element.selected_source.duration != 0 ){
 223+ this.duration = this.media_element.selected_source.duration;
 224+ this.start_offset = this.media_element.selected_source.start_offset;
 225+ this.start_ntp = this.media_element.selected_source.start_ntp;
 226+ this.end_ntp = this.media_element.selected_source.end_ntp;
 227+ }else{
 228+ //update start end_ntp if duration !=0 (set from plugin)
 229+ if(this.duration && this.duration !=0){
 230+ this.start_ntp = '0:0:0';
 231+ this.end_ntp = seconds2ntp( this.duration );
 232+ }
 233+ }
 234+ //return the duration
 235+ return this.duration;
 236+ },
 237+ /* get the duration in ntp format */
 238+ getDurationNTP:function(){
 239+ return seconds2ntp(this.getDuration());
 240+ },
 241+ /*
 242+ * wrapEmebedContainer
 243+ * wraps the embed code into a container to better support playlist function
 244+ * (where embed element is swapped for next clip
 245+ * (where plugin method does not support playlsits)
 246+ */
 247+ wrapEmebedContainer:function(embed_code){
 248+ //check if parent clip is set( ie we are in a playlist so name the embed container by playlistID)
 249+ var id = (this.pc!=null)?this.pc.pp.id:this.id;
 250+ return '<div id="mv_ebct_'+id+'" style="width:'+this.width+'px;height:'+this.height+'px;">' +
 251+ embed_code +
 252+ '</div>';
 253+ },
 254+ getEmbedHTML : function(){
 255+ //return this.wrapEmebedContainer( this.getEmbedObj() );
 256+ return 'function getEmbedHTML should be overitten by embedLib ';
 257+ },
 258+ //do seek function (should be overwritten by implementing embedLibs)
 259+ // first check if seek can be done on locally downloaded content.
 260+ doSeek : function( perc ){
 261+ js_log('f:mv_embed:doSeek:'+perc);
 262+ if( this.supportsURLTimeEncoding() ){
 263+ js_log('Seeking to ' + this.seek_time_sec + ' (local copy of clip not loaded at' + perc + '%)');
 264+ this.stop();
 265+ this.didSeekJump=true;
 266+ //update the slider
 267+ this.setSliderValue( perc );
 268+ }
 269+
 270+ //do play in 100ms (give things time to clear)
 271+ setTimeout('$j(\'#' + this.id + '\').get(0).play()',100);
 272+ },
 273+ doEmbedHTML:function()
 274+ {
 275+ js_log('f:doEmbedHTML');
 276+ js_log('thum disp:'+this.thumbnail_disp);
 277+ var _this = this;
 278+ this.closeDisplayedHTML();
 279+
 280+// if(!this.selected_player){
 281+// return this.getPluginMissingHTML();
 282+ //Set "loading" here
 283+ $j('#mv_embedded_player_'+_this.id).html(''+
 284+ '<div style="color:black;width:'+this.width+'px;height:'+this.height+'px;">' +
 285+ gM('loading_plugin') +
 286+ '</div>'
 287+ );
 288+ // schedule embedding
 289+ this.selected_player.load(function()
 290+ {
 291+ js_log('performing embed for ' + _this.id);
 292+ var embed_code = _this.getEmbedHTML();
 293+ //js_log(embed_code);
 294+ $j('#mv_embedded_player_'+_this.id).html(embed_code);
 295+ });
 296+ },
 297+ /* todo abstract out onClipDone chain of functions and merge with textInterface */
 298+ onClipDone:function(){
 299+ //stop the clip (load the thumbnail etc)
 300+ this.stop();
 301+ var _this = this;
 302+
 303+ //if the clip resolution is < 320 don't do fancy onClipDone stuff
 304+ if(this.width<300){
 305+ return ;
 306+ }
 307+ this.onClipDone_disp=true;
 308+ this.thumbnail_disp=true;
 309+ //make sure we are not in preview mode( no end clip actions in preview mode)
 310+ if( this.preview_mode )
 311+ return ;
 312+
 313+ $j('#img_thumb_'+this.id).css('zindex',1);
 314+ $j('#big_play_link_'+this.id).hide();
 315+ //add the liks_info_div black back
 316+ $j('#dc_'+this.id).append('<div id="liks_info_'+this.id+'" ' +
 317+ 'style="width:' +parseInt(parseInt(this.width)/2)+'px;'+
 318+ 'height:'+ parseInt(parseInt(this.height)) +'px;'+
 319+ 'position:absolute;top:10px;overflow:auto'+
 320+ 'width: '+parseInt( ((parseInt(this.width)/2)-15) ) + 'px;'+
 321+ 'left:'+ parseInt( ((parseInt(this.width)/2)+15) ) +'px;">'+
 322+ '</div>' +
 323+ '<div id="black_back_'+this.id+'" ' +
 324+ 'style="z-index:-2;position:absolute;background:#000;' +
 325+ 'top:0px;left:0px;width:'+parseInt(this.width)+'px;' +
 326+ 'height:'+parseInt(this.height)+'px;">' +
 327+ '</div>'
 328+ );
 329+
 330+ //start animation (make thumb small in upper left add in div for "loading"
 331+ $j('#img_thumb_'+this.id).animate({
 332+ width:parseInt(parseInt(_this.width)/2),
 333+ height:parseInt(parseInt(_this.height)/2),
 334+ top:20,
 335+ left:10
 336+ },
 337+ 1000,
 338+ function(){
 339+ //animation done.. add "loading" to div if empty
 340+ if($j('#liks_info_'+_this.id).html()==''){
 341+ $j('#liks_info_'+_this.id).html(gM('loading_txt'));
 342+ }
 343+ }
 344+ )
 345+ //now load roe if run the showNextPrevLinks
 346+ if(this.roe && this.media_element.addedROEData==false){
 347+ do_request(this.roe, function(data)
 348+ {
 349+ _this.media_element.addROE(data);
 350+ _this.getNextPrevLinks();
 351+ });
 352+ }else{
 353+ this.getNextPrevLinks();
 354+ }
 355+ },
 356+ //@@todo we should merge getNextPrevLinks with textInterface .. there is repeated code between them.
 357+ getNextPrevLinks:function(){
 358+ js_log('f:getNextPrevLinks');
 359+ var anno_track_url = null;
 360+ var _this = this;
 361+ //check for annoative track
 362+ $j.each(this.media_element.sources, function(inx, n){
 363+ if(n.mime_type=='text/cmml'){
 364+ if( n.id == 'Anno_en'){
 365+ anno_track_url = n.src;
 366+ }
 367+ }
 368+ });
 369+ if( anno_track_url ){
 370+ js_log('found annotative track:'+ anno_track_url);
 371+ //zero out seconds (should improve cache hit rate and generally expands metadata search)
 372+ //@@todo this could be repalced with a regExp
 373+ var annoURL = parseUri(anno_track_url);
 374+ var times = annoURL.queryKey['t'].split('/');
 375+ var stime_parts = times[0].split(':');
 376+ var etime_parts = times[1].split(':');
 377+ //zero out the hour:
 378+ var new_start = stime_parts[0]+':'+'0:0';
 379+ //zero out the end sec
 380+ var new_end = (etime_parts[0]== stime_parts[0])? (etime_parts[0]+1)+':0:0' :etime_parts[0]+':0:0';
 381+
 382+ var etime_parts = times[1].split(':');
 383+
 384+ var new_anno_track_url = annoURL.protocol +'://'+ annoURL.host + annoURL.path +'?';
 385+ $j.each(annoURL.queryKey, function(i, val){
 386+ new_anno_track_url +=(i=='t')?'t='+new_start+'/'+new_end +'&' :
 387+ i+'='+ val+'&';
 388+ });
 389+ var request_key = new_start+'/'+new_end;
 390+ //check the anno_data cache:
 391+ //@@todo search cache see if current is in range.
 392+ if(this.anno_data_cache){
 393+ js_log('anno data found in cache: '+request_key);
 394+ this.showNextPrevLinks();
 395+ }else{
 396+ do_request(new_anno_track_url, function(cmml_data){
 397+ js_log('raw response: '+ cmml_data);
 398+ if(typeof cmml_data == 'string')
 399+ {
 400+ var parser=new DOMParser();
 401+ js_log('Parse CMML data:' + cmml_data);
 402+ cmml_data=parser.parseFromString(cmml_data,"text/xml");
 403+ }
 404+ //init anno_data_cache
 405+ if(!_this.anno_data_cache)
 406+ _this.anno_data_cache={};
 407+ //grab all metadata and put it into the anno_data_cache:
 408+ $j.each(cmml_data.getElementsByTagName('clip'), function(inx, clip){
 409+ _this.anno_data_cache[ $j(clip).attr("id") ]={
 410+ 'start_time_sec':ntp2seconds($j(clip).attr("start").replace('npt:','')),
 411+ 'end_time_sec':ntp2seconds($j(clip).attr("end").replace('npt:','')),
 412+ 'time_req':$j(clip).attr("start").replace('npt:','')+'/'+$j(clip).attr("end").replace('npt:','')
 413+ };
 414+ //grab all its meta
 415+ _this.anno_data_cache[ $j(clip).attr("id") ]['meta']={};
 416+ $j.each(clip.getElementsByTagName('meta'),function(imx, meta){
 417+ //js_log('adding meta: '+ $j(meta).attr("name")+ ' = '+ $j(meta).attr("content"));
 418+ _this.anno_data_cache[$j(clip).attr("id")]['meta'][$j(meta).attr("name")]=$j(meta).attr("content");
 419+ });
 420+ });
 421+ _this.showNextPrevLinks();
 422+ });
 423+ }
 424+ }else{
 425+ js_log('no annotative track found');
 426+ $j('#liks_info_'+this.id).html('no metadata found for next, previous links');
 427+ }
 428+ //query current request time +|- 60s to get prev next speech links.
 429+ },
 430+ showNextPrevLinks:function(){
 431+ js_log('f:showNextPrevLinks');
 432+ //int requested links:
 433+ var link = {
 434+ 'prev':'',
 435+ 'current':'',
 436+ 'next':''
 437+ }
 438+ var curTime = this.getTimeReq().split('/');
 439+
 440+ var s_sec = ntp2seconds(curTime[0]);
 441+ var e_sec = ntp2seconds(curTime[1]);
 442+ js_log('showNextPrevLinks: req time: '+ s_sec + ' to ' + e_sec);
 443+ //now we have all the data in anno_data_cache
 444+ var current_done=false;
 445+ for(var clip_id in this.anno_data_cache){ //for in loop oky for object
 446+ var clip = this.anno_data_cache[clip_id];
 447+ //js_log('on clip:'+ clip_id);
 448+ //set prev_link (if cur_link is still empty)
 449+ if( s_sec > clip.end_time_sec){
 450+ link.prev = clip_id;
 451+ js_log('showNextPrevLinks: ' + s_sec + ' < ' + clip.end_time_sec + ' set prev');
 452+ }
 453+
 454+ if(e_sec==clip.end_time_sec && s_sec== clip.start_time_sec)
 455+ current_done = true;
 456+ //current clip is not done:
 457+ if( e_sec < clip.end_time_sec && link.current=='' && !current_done){
 458+ link.current = clip_id;
 459+ js_log('showNextPrevLinks: ' + e_sec + ' < ' + clip.end_time_sec + ' set current');
 460+ }
 461+
 462+ //set end clip (first clip where start time is > end_time of req
 463+ if( e_sec < clip.start_time_sec && link.next==''){
 464+ link.next = clip_id;
 465+ js_log('showNextPrevLinks: '+ e_sec + ' < '+ clip.start_time_sec + ' && ' + link.next );
 466+ }
 467+ }
 468+ var html='';
 469+ if(link.prev=='' && link.current=='' && link.next==''){
 470+ html='<p><a href="'+this.media_element.linkbackgetMsg+'">clip page</a>';
 471+ }else{
 472+ for(var link_type in link){
 473+ var link_id = link[link_type];
 474+ if(link_id!=''){
 475+ var clip = this.anno_data_cache[link_id];
 476+ var title_msg='';
 477+ for(var j in clip['meta']){
 478+ title_msg+=j.replace(/_/g,' ') +': ' +clip['meta'][j].replace(/_/g,' ') +" <br>";
 479+ }
 480+ var time_req = clip.time_req;
 481+ if(link_type=='current') //if current start from end of current clip play to end of current meta:
 482+ time_req = curTime[1]+ '/' + seconds2ntp( clip.end_time_sec );
 483+
 484+ //do special linkbacks for metavid content:
 485+ var regTimeCheck = new RegExp(/[0-9]+:[0-9]+:[0-9]+\/[0-9]+:[0-9]+:[0-9]+/);
 486+ html+='<p><a ';
 487+ if( regTimeCheck.test( this.media_element.linkback ) ){
 488+ html+=' href="'+ this.media_element.linkback.replace(regTimeCheck,time_req) +'" ';
 489+ }else{
 490+ html+=' href="#" onClick="$j(\'#'+this.id+'\').get(0).playByTimeReq(\''+
 491+ time_req + '\'); return false; "';
 492+ }
 493+ html+=' title="' + title_msg + '">' +
 494+ gM(link_type+'_clip_msg') +
 495+ '</a><br><span style="font-size:small">'+ title_msg +'<span></p>';
 496+ }
 497+ }
 498+ }
 499+ //js_og("should set html:"+ html);
 500+ $j('#liks_info_'+this.id).html(html);
 501+ },
 502+ playByTimeReq: function(time_req){
 503+ js_log('f:playByTimeReq: '+time_req );
 504+ this.stop();
 505+ this.updateVideoTimeReq(time_req);
 506+ this.play();
 507+ },
 508+ doThumbnailHTML:function()
 509+ {
 510+ var _this = this;
 511+ js_log('f:doThumbnailHTML'+ this.thumbnail_disp);
 512+ this.closeDisplayedHTML();
 513+ this.thumbnail_disp = true;
 514+
 515+ $j('#mv_embedded_player_'+this.id).html( this.getThumbnailHTML() );
 516+ this.paused = true;
 517+ },
 518+ refreshControlsHTML:function(){
 519+ js_log('refreshing controls HTML');
 520+ if($j('#mv_embedded_controls_'+this.id).length==0)
 521+ {
 522+ js_log('#mv_embedded_controls_'+this.id + ' not present, returning');
 523+ return;
 524+ }else{
 525+ $j('#mv_embedded_controls_'+this.id).html( this.getControlsHTML() );
 526+ ctrlBuilder.addControlHooks(this);
 527+ }
 528+ },
 529+ getControlsHTML:function()
 530+ {
 531+ return ctrlBuilder.getControls( this );
 532+ },
 533+ getHTML : function (){
 534+ //@@todo check if we have sources avaliable
 535+ js_log('f:getHTML : ' + this.id );
 536+ var _this = this;
 537+ var html_code = '';
 538+ html_code = '<div id="videoPlayer_'+this.id+'" style="width:'+this.width+'px;" class="videoPlayer">';
 539+ html_code += '<div style="width:'+parseInt(this.width)+'px;height:'+parseInt(this.height)+'px;" id="mv_embedded_player_'+this.id+'">' +
 540+ this.getThumbnailHTML() +
 541+ '</div>';
 542+ //js_log("mvEmbed:controls "+ typeof this.controls);
 543+ if(this.controls)
 544+ {
 545+ js_log("f:getHTML:AddControls");
 546+ html_code +='<div id="mv_embedded_controls_' + this.id + '" class="controls" style="width:' + this.width + 'px">';
 547+ html_code += this.getControlsHTML();
 548+ html_code +='</div>';
 549+ //block out some space by encapulating the top level div
 550+ $j(this).wrap('<div style="width:'+parseInt(this.width)+'px;height:'
 551+ +(parseInt(this.height)+ctrlBuilder.height)+'px"></div>');
 552+ }
 553+ html_code += '</div>'; //videoPlayer div close
 554+ //js_log('should set: '+this.id);
 555+ $j(this).html( html_code );
 556+ //add hooks once Controls are in DOM
 557+ ctrlBuilder.addControlHooks(this);
 558+
 559+ //js_log('set this to: ' + $j(this).html() );
 560+ //alert('stop');
 561+ //if auto play==true directly embed the plugin
 562+ if(this.autoplay)
 563+ {
 564+ js_log('activating autoplay');
 565+ this.play();
 566+ }
 567+ },
 568+ /*
 569+ * get missing plugin html (check for user included code)
 570+ */
 571+ getPluginMissingHTML : function(){
 572+ //keep the box width hight:
 573+ var out = '<div style="width:'+this.width+'px;height:'+this.height+'px">';
 574+ if(this.user_missing_plugin_html){
 575+ out+= this.user_missing_plugin_html;
 576+ }else{
 577+ out+= gM('generic_missing_plugin') + ' or <a title="'+gM('download_clip')+'" href="'+this.src +'">'+gM('download_clip')+'</a>';
 578+ }
 579+ return out + '</div>';
 580+ },
 581+ updateVideoTimeReq:function(time_req){
 582+ js_log('f:updateVideoTimeReq');
 583+ var time_parts =time_req.split('/');
 584+ this.updateVideoTime(time_parts[0], time_parts[1]);
 585+ },
 586+ //update video time
 587+ updateVideoTime:function(start_ntp, end_ntp){
 588+ //update media
 589+ this.media_element.updateSourceTimes( start_ntp, end_ntp );
 590+ //update mv_time
 591+ this.setStatus(start_ntp+'/'+end_ntp);
 592+ //reset slider
 593+ this.setSliderValue(0);
 594+ //reset seek_offset:
 595+ if(this.media_element.selected_source.supports_url_time_encoding)
 596+ this.seek_time_sec=0;
 597+ else
 598+ this.seek_time_sec=ntp2seconds(start_ntp);
 599+ },
 600+ //@@todo overwite by embed library if we can render frames natavily
 601+ renderTimelineThumbnail:function( options ){
 602+ var my_thumb_src = this.media_element.getThumbnailURL();
 603+
 604+ if( my_thumb_src.indexOf('t=') !== -1){
 605+ var time_ntp = seconds2ntp ( options.time + parseInt(this.start_offset) );
 606+ my_thumb_src = getUpdateTimeURL( my_thumb_src, time_ntp, options.size );
 607+ }
 608+ var thumb_class = (typeof options['thumb_class'] !='undefined')? options['thumb_class'] : '';
 609+ return '<div class="' + thumb_class + '" src="' + my_thumb_src +'" '+
 610+ 'style="height:' + options.height + 'px;' +
 611+ 'width:' + options.width + 'px" >' +
 612+ '<img src="' + my_thumb_src +'" '+
 613+ 'style="height:' + options.height + 'px;' +
 614+ 'width:' + options.width + 'px">' +
 615+ '</div>';
 616+ },
 617+ updateThumbTimeNTP:function( time){
 618+ this.updateThumbTime( ntp2seconds(time) - parseInt(this.start_offset) );
 619+ },
 620+ updateThumbTime:function( float_sec ){
 621+ //js_log('updateThumbTime:'+float_sec);
 622+ var _this = this;
 623+ if( typeof this.org_thum_src=='undefined' ){
 624+ this.org_thum_src = this.media_element.getThumbnailURL();
 625+ }
 626+ if( this.org_thum_src.indexOf('t=') !== -1){
 627+ this.last_thumb_url = getUpdateTimeURL(this.org_thum_src,seconds2ntp( float_sec + parseInt(this.start_offset)));
 628+ if(!this.thumbnail_updating){
 629+ this.updateThumbnail(this.last_thumb_url ,false);
 630+ this.last_thumb_url =null;
 631+ }
 632+ }
 633+ },
 634+ //for now provide a src url .. but need to figure out how to copy frames from video for plug-in based thumbs
 635+ updateThumbPerc:function( perc ){
 636+ return this.updateThumbTime( (this.getDuration() * perc) );
 637+ },
 638+ //updates the thumbnail if the thumbnail is being displayed
 639+ updateThumbnail : function(src, quick_switch){
 640+ //make sure we don't go to the same url if we are not already updating:
 641+ if( !this.thumbnail_updating && $j('#img_thumb_'+this.id).attr('src')== src )
 642+ return false;
 643+ //if we are already updating don't issue a new update:
 644+ if( this.thumbnail_updating && $j('#new_img_thumb_'+this.id).attr('src')== src )
 645+ return false;
 646+
 647+ js_log('update thumb: ' + src);
 648+
 649+ if(quick_switch){
 650+ $j('#img_thumb_'+this.id).attr('src', src);
 651+ }else{
 652+ var _this = this;
 653+ //if still animating remove new_img_thumb_
 654+ if(this.thumbnail_updating==true)
 655+ $j('#new_img_thumb_'+this.id).stop().remove();
 656+
 657+ if(this.thumbnail_disp){
 658+ js_log('set to thumb:'+ src);
 659+ this.thumbnail_updating=true;
 660+ $j('#dc_'+this.id).append('<img src="'+src+'" ' +
 661+ 'style="display:none;position:absolute;zindex:2;top:0px;left:0px;" ' +
 662+ 'width="'+this.width+'" height="'+this.height+'" '+
 663+ 'id = "new_img_thumb_'+this.id+'" />');
 664+ //js_log('appended: new_img_thumb_');
 665+ $j('#new_img_thumb_'+this.id).fadeIn("slow", function(){
 666+ //once faded in remove org and rename new:
 667+ $j('#img_thumb_'+_this.id).remove();
 668+ $j('#new_img_thumb_'+_this.id).attr('id', 'img_thumb_'+_this.id);
 669+ $j('#img_thumb_'+_this.id).css('zindex','1');
 670+ _this.thumbnail_updating=false;
 671+ //js_log("done fadding in "+ $j('#img_thumb_'+_this.id).attr("src"));
 672+
 673+ //if we have a thumb queued update to that
 674+ if(_this.last_thumb_url){
 675+ var src_url =_this.last_thumb_url;
 676+ _this.last_thumb_url=null;
 677+ _this.updateThumbnail(src_url);
 678+ }
 679+ });
 680+ }
 681+ }
 682+ },
 683+ /** Returns the HTML code for the video when it is in thumbnail mode.
 684+ This includes the specified thumbnail as well as buttons for
 685+ playing, configuring the player, inline cmml display, HTML linkback,
 686+ download, and embed code.
 687+ */
 688+ getThumbnailHTML : function ()
 689+ {
 690+ var thumb_html = '';
 691+ var class_atr='';
 692+ var style_atr='';
 693+ //if(this.class)class_atr = ' class="'+this.class+'"';
 694+ //if(this.style)style_atr = ' style="'+this.style+'"';
 695+ // else style_atr = 'overflow:hidden;height:'+this.height+'px;width:'+this.width+'px;';
 696+ this.thumbnail = this.media_element.getThumbnailURL();
 697+
 698+ //put it all in the div container dc_id
 699+ thumb_html+= '<div id="dc_'+this.id+'" style="position:relative;'+
 700+ ' overflow:hidden; top:0px; left:0px; width:'+this.playerPixelWidth()+'px; height:'+this.playerPixelHeight()+'px; z-index:0;">'+
 701+ '<img width="'+this.playerPixelWidth()+'" height="'+this.playerPixelHeight()+'" style="position:relative;width:'+this.playerPixelWidth()+';height:'+this.playerPixelHeight()+'"' +
 702+ ' id="img_thumb_'+this.id+'" src="' + this.thumbnail + '">';
 703+
 704+ if(this.play_button==true)
 705+ thumb_html+=this.getPlayButton();
 706+
 707+ thumb_html+='</div>';
 708+ return thumb_html;
 709+ },
 710+ getEmbeddingHTML:function()
 711+ {
 712+ var thumbnail = this.media_element.getThumbnailURL();
 713+
 714+ var embed_thumb_html;
 715+ if(thumbnail.substring(0,1)=='/'){
 716+ eURL = parseUri(mv_embed_path);
 717+ embed_thumb_html = eURL.protocol + '://' + eURL.host + thumbnail;
 718+ //js_log('set from mv_embed_path:'+embed_thumb_html);
 719+ }else{
 720+ embed_thumb_html = (thumbnail.indexOf('http://')!=-1)?thumbnail:mv_embed_path + thumbnail;
 721+ }
 722+ var embed_code_html = '&lt;script type=&quot;text/javascript&quot; ' +
 723+ 'src=&quot;'+mv_embed_path+'mv_embed.js&quot;&gt;&lt;/script&gt' +
 724+ '&lt;video ';
 725+ if(this.roe){
 726+ embed_code_html+='roe=&quot;'+this.roe+'&quot; &gt;';
 727+ }else{
 728+ embed_code_html+='src=&quot;'+this.src+'&quot; ' +
 729+ 'thumbnail=&quot;'+embed_thumb_html+'&quot;&gt;';
 730+ }
 731+ //close the video tag
 732+ embed_code_html+='&lt;/video&gt;';
 733+
 734+ return embed_code_html;
 735+ },
 736+ doOptionsHTML:function()
 737+ {
 738+ var sel_id = (this.pc!=null)?this.pc.pp.id:this.id;
 739+ var pos = $j('#options_button_'+sel_id).offset();
 740+ pos['top']=pos['top']+24;
 741+ pos['left']=pos['left']-124;
 742+ //js_log('pos of options button: t:'+pos['top']+' l:'+ pos['left']);
 743+ $j('#mv_embedded_options_'+sel_id).css(pos).toggle();
 744+ return;
 745+ },
 746+ getPlayButton:function(id){
 747+ if(!id)id=this.id;
 748+ return '<div id="big_play_link_'+id+'" class="large_play_button" '+
 749+ 'style="left:'+((this.playerPixelWidth()-130)/2)+'px;'+
 750+ 'top:'+((this.playerPixelHeight()-96)/2)+'px;"></div>';
 751+ },
 752+ //display the code to remotely embed this video:
 753+ showEmbedCode : function(embed_code){
 754+ if(!embed_code)
 755+ embed_code = this.getEmbeddingHTML();
 756+ var o='';
 757+ if(this.linkback){
 758+ o+='<a class="email" href="'+this.linkback+'">Share Clip via Link</a> '+
 759+ '<p>or</p> ';
 760+ }
 761+ o+='<span style="color:#FFF;font-size:14px;">Embed Clip in Blog or Site</span>'+
 762+ '<div class="embed_code"> '+
 763+ '<textarea onClick="this.select();" id="embedding_user_html_'+this.id+'" name="embed">' +
 764+ embed_code+
 765+ '</textarea> '+
 766+ '<button onClick="$j(\'#'+this.id+'\').get(0).copyText(); return false;" class="copy_to_clipboard">Copy to Clipboard</button> '+
 767+ '</div> '+
 768+ '</div>';
 769+ this.displayHTML(o);
 770+ },
 771+ copyText:function(){
 772+ $j('#embedding_user_html_'+this.id).focus().select();
 773+ if(document.selection){
 774+ CopiedTxt = document.selection.createRange();
 775+ CopiedTxt.execCommand("Copy");
 776+ }
 777+ },
 778+ showTextInterface:function(){
 779+ var _this = this;
 780+ //display the text container with loading text:
 781+ //@@todo support position config
 782+ var loc = $j(this).position();
 783+ if($j('#metaBox_'+this.id).length==0){
 784+ $j(this).after('<div style="position:absolute;z-index:10;'+
 785+ 'top:' + (loc.top) + 'px;' +
 786+ 'left:' + (parseInt( loc.left ) + parseInt(this.width) + 10 )+'px;' +
 787+ 'height:'+ parseInt( this.height )+'px;width:400px;' +
 788+ 'background:white;border:solid black;' +
 789+ 'display:none;" ' +
 790+ 'id="metaBox_' + this.id + '">'+
 791+ gM('loading_txt') +
 792+ '</div>');
 793+ }
 794+ //fade in the text display
 795+ $j('#metaBox_'+this.id).fadeIn("fast");
 796+ //check if textObj present:
 797+ if(typeof this.textInterface == 'undefined' ){
 798+ //load the default text interface:
 799+ mvJsLoader.doLoad({
 800+ 'textInterface':'libTimedText/mv_timed_text.js',
 801+ '$j.fn.hoverIntent':'jquery/plugins/jquery.hoverIntent.js'
 802+ }, function(){
 803+
 804+ _this.textInterface = new textInterface( _this );
 805+ //show interface
 806+ _this.textInterface.show();
 807+ js_log("NEW TEXT INTERFACE");
 808+ for(var i in _this.textInterface.availableTracks){
 809+ js_log("tracks in new interface: "+_this.id+ ' tid:' + i);
 810+ }
 811+ }
 812+ );
 813+ }else{
 814+ //show interface
 815+ this.textInterface.show();
 816+ }
 817+ },
 818+ closeTextInterface:function(){
 819+ js_log('closeTextInterface '+ typeof this.textInterface);
 820+ if(typeof this.textInterface !== 'undefined' ){
 821+ this.textInterface.close();
 822+ }
 823+ },
 824+ /** Generic function to display custom HTML inside the mv_embed element.
 825+ The code should call the closeDisplayedHTML function to close the
 826+ display of the custom HTML and restore the regular mv_embed display.
 827+ @param {String} HTML code for the selection list.
 828+ */
 829+ displayHTML:function(html_code)
 830+ {
 831+ var sel_id = (this.pc!=null)?this.pc.pp.id:this.id;
 832+
 833+ if(!this.supports['overlays'])
 834+ this.stop();
 835+
 836+ //put select list on-top
 837+ //make sure the parent is relatively positioned:
 838+ $j('#'+sel_id).css('position', 'relative');
 839+ //set height width (check for playlist container)
 840+ var width = (this.pc)?this.pc.pp.width:this.playerPixelWidth();
 841+ var height = (this.pc)?this.pc.pp.height:this.playerPixelHeight();
 842+
 843+ if(this.pc)
 844+ height+=(this.pc.pp.pl_layout.title_bar_height + this.pc.pp.pl_layout.control_height);
 845+
 846+ var fade_in = true;
 847+ if($j('#blackbg_'+sel_id).length!=0)
 848+ {
 849+ fade_in = false;
 850+ $j('#blackbg_'+sel_id).remove();
 851+ }
 852+ //fade in a black bg div ontop of everything
 853+ var div_code = '<div id="blackbg_'+sel_id+'" class="videoComplete" ' +
 854+ 'style="height:'+parseInt(height)+'px;width:'+parseInt(width)+'px;">'+
 855+// '<span class="displayHTML" id="con_vl_'+this.id+'" style="position:absolute;top:20px;left:20px;color:white;">' +
 856+ '<div class="videoOptionsComplete">'+
 857+ //@@TODO: this style should go to .css
 858+ '<span style="float:right;margin-right:10px">' +
 859+ '<a href="#" style="color:white;" onClick="$j(\'#'+sel_id+'\').get(0).closeDisplayedHTML();return false;">close</a>' +
 860+ '</span>'+
 861+ '<div id="mv_disp_inner_'+sel_id+'" style="padding-top:10px;">'+
 862+ html_code
 863+ +'</div>'+
 864+// close_link+'</span>'+
 865+ '</div></div>';
 866+ $j('#'+sel_id).prepend(div_code);
 867+ if (fade_in)
 868+ $j('#blackbg_'+sel_id).fadeIn("slow");
 869+ else
 870+ $j('#blackbg_'+sel_id).show();
 871+ return false; //onclick action return false
 872+ },
 873+ /** Close the custom HTML displayed using displayHTML and restores the
 874+ regular mv_embed display.
 875+ */
 876+ closeDisplayedHTML:function(){
 877+ var sel_id = (this.pc!=null)?this.pc.pp.id:this.id;
 878+ $j('#blackbg_'+sel_id).fadeOut("slow", function(){
 879+ $j('#blackbg_'+sel_id).remove();
 880+ });
 881+ return false;//onclick action return false
 882+ },
 883+ selectPlaybackMethod:function(){
 884+ //get id (in case where we have a parent container)
 885+ var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
 886+
 887+ var _this=this;
 888+ var out='<span style="color:#FFF;background-color:black;"><blockquote style="background-color:black;">';
 889+ var _this=this;
 890+ //js_log('selected src'+ _this.media_element.selected_source.url);
 891+ $j.each(this.media_element.getPlayableSources(), function(index, source)
 892+ {
 893+ var default_player = embedTypes.players.defaultPlayer( source.getMIMEType() );
 894+ var source_select_code = '$j(\'#'+this_id+'\').get(0).closeDisplayedHTML(); $j(\'#'+_this.id+'\').get(0).media_element.selectSource(\''+index+'\');';
 895+
 896+ //var player_code = _this.getPlayerSelectList( source.getMIMEType(), index, source_select_code);
 897+
 898+ var is_selected = (source == _this.media_element.selected_source);
 899+ var image_src = mv_embed_path+'images/stream/';
 900+ if( source.mime_type == 'video/x-flv' ){
 901+ image_src += 'flash_icon_';
 902+ }else if( source.mime_type == 'video/h264'){
 903+ //for now all mp4 content is pulled from archive.org (so use archive.org icon)
 904+ image_src += 'archive_org_';
 905+ }else{
 906+ image_src += 'fish_xiph_org_';
 907+ }
 908+ image_src += is_selected ? 'color':'bw';
 909+ image_src += '.png';
 910+ if (default_player)
 911+ {
 912+ out += '<img src="'+image_src+'"/>';
 913+ if( ! is_selected )
 914+ out+='<a href="#" onClick="' + source_select_code + 'embedTypes.players.userSelectPlayer(\''+default_player.id+'\',\''+source.getMIMEType()+'\'); return false;">';
 915+ out += source.getTitle()+ (is_selected?'</a>':'') + ' ';
 916+ //output the player select code:
 917+ var supporting_players = embedTypes.players.getMIMETypePlayers( source.getMIMEType() );
 918+ out+='<div id="player_select_list_' + index + '" class="player_select_list"><ul>';
 919+ for(var i=0; i < supporting_players.length ; i++){
 920+ if( _this.selected_player.id == supporting_players[i].id && is_selected ){
 921+ out+='<li style="border-style:dashed;margin-left:20px;">'+
 922+ '<img border="0" width="16" height="16" src="'+mv_embed_path+'images/plugin.png">'+
 923+ supporting_players[i].getName() +
 924+ '</li>';
 925+ }else{
 926+ //else gray plugin and the plugin with link to select
 927+ out+='<li style="margin-left:20px;">'+
 928+ '<a href="#" onClick="'+ source_select_code + 'embedTypes.players.userSelectPlayer(\''+supporting_players[i].id+'\',\''+ source.getMIMEType()+'\');return false;">'+
 929+ '<img border="0" width="16" height="16" src="'+mv_embed_path+'images/plugin_disabled.png">'+
 930+ supporting_players[i].getName() +
 931+ '</a>'+
 932+ '</li>';
 933+ }
 934+ }
 935+ out+='</ul></div>';
 936+ }else
 937+ out+= source.getTitle() + ' - no player available';
 938+ });
 939+ out+='</blockquote></span>';
 940+ this.displayHTML(out);
 941+ },
 942+ /*download list is exessivly complicated ... rewrite for clarity: */
 943+ showVideoDownload:function(){
 944+ //load the roe if avaliable (to populate out download options:
 945+ js_log('f:showVideoDownload '+ this.roe + ' ' + this.media_element.addedROEData);
 946+ if(this.roe && this.media_element.addedROEData==false){
 947+ var _this = this;
 948+ this.displayHTML(gM('loading_txt'));
 949+ do_request(this.roe, function(data)
 950+ {
 951+ _this.media_element.addROE(data);
 952+ $j('#mv_disp_inner_'+_this.id).html(_this.getShowVideoDownload());
 953+ });
 954+ }else{
 955+ this.displayHTML(this.getShowVideoDownload());
 956+ }
 957+ },
 958+ getShowVideoDownload:function(){
 959+ var out='<b style="color:white;">'+gM('download_segment')+'</b><br>';
 960+ out+='<span style="color:white"><blockquote style="background:#000">';
 961+ var dl_list='';
 962+ var dl_txt_list='';
 963+
 964+ $j.each(this.media_element.getSources(), function(index, source){
 965+ var dl_line = '<li>' + '<a style="color:white" href="' + source.getURI() +'"> '
 966+ + source.getTitle()+'</a> '+ '</li>'+"\n";
 967+ if( source.getURI().indexOf('?t=')!==-1){
 968+ out+=dl_line;
 969+ }else if(this.getMIMEType()=="text/cmml"){
 970+ dl_txt_list+=dl_line;
 971+ }else{
 972+ dl_list+=dl_line;
 973+ }
 974+ });
 975+ if(dl_list!='')
 976+ out+='</blockquote>'+gM('download_full')+'<blockquote style="background:#000">' + dl_list + '</blockquote>';
 977+ if(dl_txt_list!='')
 978+ out+='</blockquote>'+gM('download_text')+'<blockquote style="background:#000">' + dl_txt_list +'</blockquote></span>';
 979+ return out;
 980+ },
 981+ /*
 982+ * base embed controls
 983+ * the play button calls
 984+ */
 985+ play:function(){
 986+ var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
 987+ js_log( "mv_embed play:" + this.id);
 988+ js_log('thum disp:'+this.thumbnail_disp);
 989+ //check if thumbnail is being displayed and embed html
 990+ if( this.thumbnail_disp ){
 991+ if( !this.selected_player ){
 992+ js_log('no selected_player');
 993+ //this.innerHTML = this.getPluginMissingHTML();
 994+ //$j(this).html(this.getPluginMissingHTML());
 995+ $j('#'+this.id).html( this.getPluginMissingHTML() );
 996+ }else{
 997+ this.doEmbedHTML();
 998+ this.onClipDone_disp=false;
 999+ this.paused=false;
 1000+ this.thumbnail_disp=false;
 1001+ }
 1002+ }else{
 1003+ //the plugin is already being displayed
 1004+ this.paused=false; //make sure we are not "paused"
 1005+ }
 1006+ $j("#mv_play_pause_button_" + this_id).attr({
 1007+ 'class':'pause_button'
 1008+ }).unbind( "click" ).click(function(){
 1009+ $j('#' + this_id ).get(0).pause();
 1010+ });
 1011+ },
 1012+ /*
 1013+ * base embed pause
 1014+ * there is no general way to pause the video
 1015+ * must be overwritten by embed object to support this functionality.
 1016+ */
 1017+ pause: function(){
 1018+ var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
 1019+ js_log('mv_embed:do pause');
 1020+ //(playing) do pause
 1021+ this.paused=true;
 1022+ //update the ctrl "paused state"
 1023+ $j("#mv_play_pause_button_" + this_id).attr({
 1024+ 'class':'play_button'
 1025+ }).unbind( "click" ).click(function(){
 1026+ $j('#'+this_id).get(0).play();
 1027+ });
 1028+ },
 1029+ /*
 1030+ * base embed stop (can be overwritten by the plugin)
 1031+ */
 1032+ stop: function(){
 1033+ var _this = this;
 1034+ js_log('mvEmbed:stop:'+this.id);
 1035+
 1036+ //no longer seeking:
 1037+ this.didSeekJump=false;
 1038+
 1039+ //first issue pause to update interface (only call the parent)
 1040+ if(this['parent_pause']){
 1041+ this.parent_pause();
 1042+ }else{
 1043+ this.pause();
 1044+ }
 1045+ //reset the currentTime:
 1046+ this.currentTime=0;
 1047+ //check if thumbnail is being displayed in which case do nothing
 1048+ if(this.thumbnail_disp){
 1049+ //already in stooped state
 1050+ js_log('already in stopped state');
 1051+ }else{
 1052+ //rewrite the html to thumbnail disp
 1053+ this.doThumbnailHTML();
 1054+ this.bufferedPercent=0; //reset buffer state
 1055+ this.setSliderValue(0);
 1056+ this.setStatus( this.getTimeReq() );
 1057+ }
 1058+ //make sure the big playbutton is has click action:
 1059+ $j('#big_play_link_' + _this.id).unbind('click').click(function(){
 1060+ $j('#' +_this.id).get(0).play();
 1061+ });
 1062+
 1063+ if(this.update_interval)
 1064+ {
 1065+ clearInterval(this.update_interval);
 1066+ this.update_interval = null;
 1067+ }
 1068+ },
 1069+ toggleMute:function(){
 1070+ var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
 1071+ js_log('f:toggleMute');
 1072+ if(this.muted){
 1073+ this.muted=false;
 1074+ $j('#volume_icon_'+this_id).removeClass('volume_off').addClass('volume_on');
 1075+ }else{
 1076+ this.muted=true;
 1077+ $j('#volume_icon_'+this_id).removeClass('volume_on').addClass('volume_off');
 1078+ }
 1079+ },
 1080+ fullscreen:function(){
 1081+ js_log('fullscreen not supported for this plugin type');
 1082+ },
 1083+ /* returns bool true if playing or paused, false if stooped
 1084+ */
 1085+ isPlaying : function(){
 1086+ if(this.thumbnail_disp){
 1087+ //in stoped state
 1088+ return false;
 1089+ }else if( this.paused ){
 1090+ //paused state
 1091+ return false;
 1092+ }else{
 1093+ return true;
 1094+ }
 1095+ },
 1096+ isPaused : function(){
 1097+ return this.isPlaying() && this.paused;
 1098+ },
 1099+ isStoped : function(){
 1100+ return this.thumbnail_disp;
 1101+ },
 1102+ playlistSupport:function(){
 1103+ //by default not supported (implemented in js)
 1104+ return false;
 1105+ },
 1106+ postEmbedJS:function(){
 1107+ return '';
 1108+ },
 1109+ getPluginEmbed : function(){
 1110+ if (window.document[this.pid]){
 1111+ return window.document[this.pid];
 1112+ }
 1113+ if (embedTypes.msie){
 1114+ return document.getElementById(this.pid );
 1115+ }else{
 1116+ if (document.embeds && document.embeds[this.pid])
 1117+ return document.embeds[this.pid];
 1118+ }
 1119+ return null;
 1120+ },
 1121+ //HELPER Functions for selected source
 1122+ /*
 1123+ * returns the selected source url for players to play
 1124+ */
 1125+ getURI : function( seek_time_sec ){
 1126+ return this.media_element.selected_source.getURI( this.seek_time_sec );
 1127+ },
 1128+ supportsURLTimeEncoding: function(){
 1129+ return this.media_element.selected_source.supports_url_time_encoding;
 1130+ },
 1131+ setSliderValue: function(perc, hide_progress){
 1132+
 1133+ //js_log('setSliderValue:'+perc+' ct:'+ this.currentTime);
 1134+ var this_id = (this.pc)?this.pc.pp.id:this.id;
 1135+ //alinment offset:
 1136+ if(!this.mv_seeker_width)
 1137+ this.mv_seeker_width = $j('#mv_seeker_slider_'+this_id).width();
 1138+
 1139+ var val = Math.round( perc * $j('#mv_seeker_'+this_id).width() - (this.mv_seeker_width*perc));
 1140+ if(val > ($j('#mv_seeker_'+this_id).width() -this.mv_seeker_width) )
 1141+ val = $j('#mv_seeker_'+this_id).width() -this.mv_seeker_width ;
 1142+ $j('#mv_seeker_slider_'+this_id).css('left', (val)+'px' );
 1143+
 1144+ //update the playback progress bar
 1145+ if( ! hide_progress ){
 1146+ $j('#mv_seeker_' + this_id + ' .mv_playback').css("width", Math.round( val + (this.mv_seeker_width*.5) ) + 'px' );
 1147+ }else{
 1148+ //hide the progress bar
 1149+ $j('#mv_seeker_' + this_id + ' .mv_playback').css("width", "0px");
 1150+ }
 1151+
 1152+ //update the buffer progress bar (if available )
 1153+ if( this.bufferedPercent!=0 ){
 1154+ //js_log('bufferedPercent: ' + this.bufferedPercent);
 1155+ if(this.bufferedPercent > 1)
 1156+ this.bufferedPercent=1;
 1157+ $j('#mv_seeker_' + this_id + ' .mv_buffer').css("width", (this.bufferedPercent*100) +'%' );
 1158+ }else{
 1159+ $j('#mv_seeker_' + this_id + ' .mv_buffer').css("width", '0px' );
 1160+ }
 1161+
 1162+ //js_log('set#mv_seeker_slider_'+this_id + ' perc in: ' + perc + ' * ' + $j('#mv_seeker_'+this_id).width() + ' = set to: '+ val + ' - '+ Math.round(this.mv_seeker_width*perc) );
 1163+ //js_log('op:' + offset_perc + ' *('+perc+' * ' + $j('#slider_'+id).width() + ')');
 1164+ },
 1165+ highlightPlaySection:function(options){
 1166+ js_log('highlightPlaySection');
 1167+ var this_id = (this.pc)?this.pc.pp.id:this.id;
 1168+ var dur = this.getDuration();
 1169+ var hide_progress = true;
 1170+ //set the left percet and update the slider:
 1171+ rel_start_sec = ( ntp2seconds( options['start']) - this.start_offset );
 1172+
 1173+ var slider_perc=0;
 1174+ if( rel_start_sec <= 0 ){
 1175+ left_perc =0;
 1176+ options['start'] = seconds2ntp( this.start_offset );
 1177+ rel_start_sec=0;
 1178+ this.setSliderValue( 0 , hide_progress);
 1179+ }else{
 1180+ left_perc = parseInt( (rel_start_sec / dur)*100 ) ;
 1181+ slider_perc = (left_perc / 100);
 1182+ }
 1183+ if( ! this.isPlaying() ){
 1184+ this.setSliderValue( slider_perc , hide_progress);
 1185+ }
 1186+
 1187+ width_perc = parseInt( (( ntp2seconds( options['end'] ) - ntp2seconds( options['start'] ) ) / dur)*100 ) ;
 1188+ if( (width_perc + left_perc) > 100 ){
 1189+ width_perc = 100 - left_perc;
 1190+ }
 1191+ //js_log('should hl: '+rel_start_sec+ '/' + dur + ' re:' + rel_end_sec+' lp:' + left_perc + ' width: ' + width_perc);
 1192+ $j('#mv_seeker_' + this_id + ' .mv_highlight').css({
 1193+ 'left':left_perc+'%',
 1194+ 'width':width_perc+'%'
 1195+ }).show();
 1196+
 1197+ this.jump_time = options['start'];
 1198+ this.seek_time_sec = ntp2seconds( options['start']);
 1199+ //trim output to
 1200+ this.setStatus( gM('seek_to')+' '+ seconds2ntp( this.seek_time_sec ) );
 1201+ js_log('DO update: ' + this.jump_time);
 1202+ this.updateThumbTime( rel_start_sec );
 1203+ },
 1204+ hideHighlight:function(){
 1205+ var this_id = (this.pc)?this.pc.pp.id:this.id;
 1206+ $j('#mv_seeker_' + this_id + ' .mv_highlight').hide();
 1207+ this.setStatus( this.getTimeReq() );
 1208+ this.setSliderValue( 0 );
 1209+ },
 1210+ setStatus:function(value){
 1211+ var id = (this.pc)?this.pc.pp.id:this.id;
 1212+ //update status:
 1213+ $j('#mv_time_'+id).html(value);
 1214+ }
 1215+}
\ No newline at end of file
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libEmbedObj/mv_quicktimeEmbed.js
@@ -61,11 +61,11 @@
6262 if ( done ) {
6363 window.clearInterval( this_.qtTimers[this_.pid] );
6464 if ( !xiphQtVersion || xiphQtVersion == '0.0' ) {
65 - $j(this_).html(getMsg('ogg-no-xiphqt'));
 65+ $j(this_).html(gM('ogg-no-xiphqt'));
6666 /*var div = document.createElement( 'div' );
6767 div.className = 'ogg-player-options';
6868 div.style.cssText = 'width:' + ( params.width - 10 ) + 'px;'
69 - div.innerHTML = this_.getMsg( 'ogg-no-xiphqt' );
 69+ div.innerHTML = this_.gM( 'ogg-no-xiphqt' );
7070 var optionsDiv = document.getElementById( params.id + '_options_box' );
7171 if ( optionsDiv ) {
7272 elt.insertBefore( div, optionsDiv.parentNode );
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libTimedText/mv_timed_text.js
@@ -86,7 +86,7 @@
8787
8888 //if nothing found anywhere update the loading icon to say no tracks found
8989 if(!default_found)
90 - $j('#mv_txt_load_'+_this.pe.id).html( getMsg('no_text_tracks_found') );
 90+ $j('#mv_txt_load_'+_this.pe.id).html( gM('no_text_tracks_found') );
9191
9292
9393 },
@@ -196,14 +196,14 @@
197197 'right:0px;bottom:0px;' +
198198 'height:'+(this.pe.height-20)+
199199 'px;overflow:auto;"><span style="display:none;" id="mv_txt_load_' + this.pe.id + '">'+
200 - getMsg('loading_txt')+'</span>' +
 200+ gM('loading_txt')+'</span>' +
201201 '</div>';
202202 },
203203 getTsSelect:function(){
204204 var _this = this;
205205 js_log('getTsSelect');
206206 var selHTML = '<div id="mvtsel_' + this.pe.id + '" style="position:absolute;background:#FFF;top:20px;left:0px;right:0px;bottom:0px;overflow:auto;">';
207 - selHTML+='<b>' + getMsg('select_transcript_set') + '</b><ul>';
 207+ selHTML+='<b>' + gM('select_transcript_set') + '</b><ul>';
208208 //debugger;
209209 for(var i in _this.availableTracks){ //for in loop ok on object
210210 var checked = ( _this.availableTracks[i].display ) ? 'checked' : '';
@@ -211,7 +211,7 @@
212212 _this.availableTracks[i].getTitle() + '</li>';
213213 }
214214 selHTML+='</ul>' +
215 - '<a href="#" onClick="document.getElementById(\'' + this.pe.id + '\').textInterface.applyTsSelect();return false;">'+getMsg('close')+'</a>'+
 215+ '<a href="#" onClick="document.getElementById(\'' + this.pe.id + '\').textInterface.applyTsSelect();return false;">'+gM('close')+'</a>'+
216216 '</div>';
217217 $j('#metaBox_'+_this.pe.id).append( selHTML );
218218 },
@@ -287,15 +287,15 @@
288288 //add in loading icon:
289289 var as_checked = (this.autoscroll)?'checked':'';
290290 out+= '<div id="tt_mmenu_'+this.pe.id+'" style="background:#AAF;font-size:small;position:absolute;top:0;height:20px;left:0px;right:0px;">' +
291 - '<a style="font-color:#000;" title="'+getMsg('close')+'" href="#" onClick="document.getElementById(\''+this.pe.id+'\').closeTextInterface();return false;">'+
 291+ '<a style="font-color:#000;" title="'+gM('close')+'" href="#" onClick="document.getElementById(\''+this.pe.id+'\').closeTextInterface();return false;">'+
292292 '<img border="0" width="16" height="16" src="'+mv_embed_path + 'images/cancel.png"></a> ' +
293 - '<a style="font-color:#000;" title="'+getMsg('select_transcript_set')+'" href="#" onClick="document.getElementById(\''+this.pe.id+'\').textInterface.getTsSelect();return false;">'+
294 - getMsg('select_transcript_set')+'</a> | ' +
 293+ '<a style="font-color:#000;" title="'+gM('select_transcript_set')+'" href="#" onClick="document.getElementById(\''+this.pe.id+'\').textInterface.getTsSelect();return false;">'+
 294+ gM('select_transcript_set')+'</a> | ' +
295295 '<input onClick="document.getElementById(\''+this.pe.id+'\').textInterface.setAutoScroll(this.checked);return false;" ' +
296 - 'type="checkbox" '+as_checked +'>'+getMsg('auto_scroll');
 296+ 'type="checkbox" '+as_checked +'>'+gM('auto_scroll');
297297 if(this.pe.media_element.linkback){
298 - out+=' | <a style="font-color:#000;" title="'+getMsg('improve_transcript')+'" href="'+this.pe.media_element.linkback+'" target="_new">'+
299 - getMsg('improve_transcript')+'</a> ';
 298+ out+=' | <a style="font-color:#000;" title="'+gM('improve_transcript')+'" href="'+this.pe.media_element.linkback+'" target="_new">'+
 299+ gM('improve_transcript')+'</a> ';
300300 }
301301 out+='</div>';
302302 return out;

Status & tagging log