r45623 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r45622‎ | r45623 | r45624 >
Date:00:33, 10 January 2009
Author:dale
Status:deferred
Tags:
Comment:
added support for firefog to add_media_wizard
other fixes to add_media_wizard
refactoring of firefogg.js
Modified paths:
  • /trunk/extensions/MetavidWiki/skins/external_media_wizard.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/firefogg.js (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/mv_remote_media_search.js (replaced) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/mv_upload.js (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libRemoteMediaSearch (deleted) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libSequencer/mv_sequencer.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/mv_embed.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/skins/mvpcf/styles.css (modified) (history)

Diff [purge]

Index: trunk/extensions/MetavidWiki/skins/external_media_wizard.js
@@ -16,14 +16,15 @@
1717 addOnloadHook( function(){
1818 var toolbar = document.getElementById("toolbar");
1919 var imE = document.createElement('img');
20 - imE.style.cursor = 'pointer';
 20+ imE.style.cursor = 'pointer';
 21+ imE.id = 'mv-add_media';
2122 imE.src = 'http://upload.wikimedia.org/wikipedia/commons/8/86/Button_add_media.png';
2223 toolbar.appendChild(imE);
23 - imE.setAttribute('onClick', 'mv_do_load_wiz()');
 24+ //imE.setAttribute('onClick', 'mv_do_load_wiz()');
2425 //addHandler only works once cuz of dom manipluations
25 - /*addHandler( imE, 'click', function() {
 26+ addHandler( imE, 'click', function() {
2627 mv_do_load_wiz();
27 - });*/
 28+ });
2829 });
2930 }
3031 var caret_pos={};
@@ -51,6 +52,13 @@
5253 'top:0;width:100%;z-index:5;filter:alpha(opacity=60);-moz-opacity: 0.6;'+
5354 'opacity: 0.6;"/>';
5455 }
 56+ //make sure the click action is still there
 57+ imE = document.getElementById('mv-add_media');
 58+ if(imE){
 59+ addHandler( imE, 'click', function() {
 60+ mv_do_load_wiz();
 61+ });
 62+ }
5563
5664 //get mv_embed path from _this_ file location:
5765 if(!mv_embed_url)
@@ -59,7 +67,7 @@
6068 //inject mv_embed
6169 if( typeof MV_EMBED_VERSION == 'undefined'){
6270 var e = document.createElement("script");
63 - e.setAttribute('src', mv_embed_url);
 71+ e.setAttribute('src', mv_embed_url);
6472 e.setAttribute('type',"text/javascript");
6573 document.getElementsByTagName("head")[0].appendChild(e);
6674 setTimeout('check_for_mv_embed();', 25);
@@ -93,7 +101,7 @@
94102 for(var i=0; i < document.getElementsByTagName('script').length; i++){
95103 var s = document.getElementsByTagName('script')[i];
96104 if( s.src.indexOf('external_media_wizard.js') != -1 ){
97 - //use the path:
 105+ //use the external_media_wizard path:
98106 return s.src= s.src.replace('external_media_wizard.js', '') + 'mv_embed/mv_embed.js';
99107 }
100108 }
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/mv_upload.js
@@ -0,0 +1,95 @@
 2+/* the upload javascript
 3+presently does hackery to work with Special:Upload page...
 4+
 5+WILL BE REPLACED WITH CODE TO ACCESS THE upload api
 6+ONCE THAT IS READY
 7+*/
 8+
 9+gMsg['upload-enable-converter'] = 'Enable video converter (to upload source video footage not yet converted to theora format) <i>more info</i>';
 10+gMsg['upload-fogg_not_installed'] = 'If you want to upload video consider installing <a href="http://firefogg.org">firefogg.org</a>, <i>more info</i>';
 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+
 16+var default_upload_options = {
 17+ 'target_div':''
 18+}
 19+
 20+var mvUploader = function(initObj){
 21+ return this.init( initObj );
 22+}
 23+mvUploader.prototype = {
 24+ init:function( iObj ){
 25+ var _this = this;
 26+ js_log('init uploader');
 27+ for(var i in default_upload_options){
 28+ if(iObj[i]){
 29+ this[i] = iObj[i];
 30+ }else{
 31+ this[i] = default_upload_options[i];
 32+ }
 33+ }
 34+ //grab firefogg.js:
 35+ mvJsLoader.doLoad({'upFirefogg' : 'libAddMedia/firefogg.js'},function(){
 36+ //for now grab the upload HTML (uggly but will be replaced by API shortly I promise )
 37+ $j.get(wgArticlePath.replace(/\$1/, 'Special:Upload'), {}, function(data){
 38+ //filter the data:
 39+ sp = data.indexOf('<div id="content">');
 40+ se = data.indexOf('<!-- end content -->');
 41+ if(sp!=-1 && se !=-1){
 42+ $j('#'+_this.target_div).html( data.substr(sp, (se-sp) ) );
 43+ }
 44+ //add firebug html if not already there: ( same as $wgEnableFirebug )
 45+ if( $j('#fogg-video-file').length==0 ){
 46+ _this.addFirebugHtml();
 47+ }else{
 48+ js_log('firefogg already there init:');
 49+ }
 50+ init_firefogg({'add_done_action':function( rTitle ){
 51+ js_log('add_done_action callback for uploader');
 52+ //call the parent insert resource preview
 53+
 54+ }
 55+ });
 56+ //set up the bindings
 57+ $j('#mw-upload-form').submit(function(){
 58+ //do an ajax submit
 59+
 60+ //(don't do the normal submit)
 61+ return false;
 62+ });
 63+ });
 64+ });
 65+ },
 66+ //same add code as specialUpload if($wgEnableFirefogg){
 67+ addFirebugHtml:function(){
 68+ $j('#mw-upload-table .mw-input :first').wrap('<div id="wg-base-upload"></div>');
 69+ //add in firefogg control
 70+ $j('#wg-base-upload').after('<p id="fogg-enable-item" >' +
 71+ '<input style="display:none" id="fogg-video-file" name="fogg-video-file" type="button" value="Select File..">' +
 72+ '<span id="wgfogg_not_installed">' +
 73+ getMsg('upload-fogg_not_installed') +
 74+ '</span>'+
 75+ '<span id="wgfogg_installed" style="display:none" >'+
 76+ '<input id="wgEnableFirefogg" type="checkbox" name="wgEnableFirefogg" >' +
 77+ getMsg('upload-enable-converter') +
 78+ '<span><br></p>');
 79+ alert('wtf');
 80+ js_log('FOUND: ' + $j('#fogg-enable-item').length + ' wg: ' + $j('#wgEnableFirefogg').length );
 81+ //add in loader dl box:
 82+ $j('#mw-upload-table').before('<div id="dlbox-centered" class="dlbox-centered" >'+
 83+ '<h5>' + getMsg('upload-in-progress') + '</h5>' +
 84+ '<div id="fogg-pbar-container" style="border:solid thin gray;width:90%;height:15px;" >' +
 85+ '<div id="fogg-progressbar" style="background:#AAC;width:0%;height:15px;"></div>' +
 86+ '</div>' +
 87+ '<span id="fogg-pstatus">0%</span>' +
 88+ '<span id="fogg-status-transcode">' + getMsg('upload-transcoded-status') + '</span>'+
 89+ '<span style="display:none" id="fogg-status-upload">' + getMsg('uploaded-status') + '</span>' +
 90+ '</div>'+
 91+ '<div class="dlbox-overlay" ></div>');
 92+ //init firefogg (check for its existance)
 93+ js_log('FOUND: ' + $j('#wgEnableFirefogg').length );
 94+ js_log('run init_firefogg');
 95+ }
 96+}
\ No newline at end of file
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/firefogg.js
@@ -0,0 +1,263 @@
 2+/**script to support firefog uploads
 3+based on http://www.firefogg.org/dev/index.html
 4+*/
 5+
 6+//add on ready hook if not being called from uploader:
 7+if(typeof mvUploader =='undefined'){
 8+ addOnloadHook(function(){
 9+ init_firefogg();
 10+ });
 11+}
 12+function init_firefogg( iObj ){
 13+ if(!iObj)
 14+ iObj = {};
 15+ //init based on if Firefogg is available
 16+ if(typeof(Firefogg) == 'undefined') {
 17+
 18+ e = document.getElementById('wgfogg_not_installed');
 19+ if(e)
 20+ e.style.display='inline';
 21+ }else{
 22+ e = document.getElementById('wgfogg_not_installed');
 23+ if(e)
 24+ e.style.display='none';
 25+
 26+ e = document.getElementById('wgfogg_installed');
 27+ if(e)
 28+ e.style.display='inline';
 29+
 30+ fe = document.getElementById('wgEnableFirefogg');
 31+ if(fe){
 32+ js_log('wgEnableFirefogg found:');
 33+ //get a new fogg object with default options
 34+ var fogg = new upFirefogg( iObj );
 35+
 36+ //make sure the checkbox accurately reflects the current state:
 37+ if(fogg.enabled == false)
 38+ fe.checked = false;
 39+
 40+ addHandler( fe, 'click', function(){
 41+ if( fogg.enabled==false ){
 42+ fogg.enable_fogg();
 43+ }else{
 44+ fogg.disable_fogg();
 45+ }
 46+ });
 47+ }else{
 48+ js_log('could not find wgEnableFirefogg');
 49+ }
 50+ }
 51+}
 52+
 53+var default_firefogg_options = {
 54+ 'add_done_action':'redirect',
 55+ 'enabled':false
 56+}
 57+var upFirefogg = function(iObj){
 58+ return this.init( iObj );
 59+}
 60+upFirefogg.prototype = {
 61+ init:function( iObj ){
 62+ for(var i in default_firefogg_options){
 63+ if(iObj[i]){
 64+ this[i] = iObj[i];
 65+ }else{
 66+ this[i] = default_firefogg_options[i];
 67+ }
 68+ }
 69+ },
 70+ enable_fogg:function(){
 71+ var _this = this;
 72+
 73+ //enable the FOGG_TOGGLE
 74+ _this.enabled=true;
 75+
 76+ //make sure file is "checked"
 77+ e = document.getElementById('wpSourceTypeFile');
 78+ if(e) e.checked = true;
 79+
 80+ //hide normal file upload stuff (this would all be much shorter code with jquery)
 81+ e = document.getElementById('wg-base-upload');
 82+ if(e) e.style.display='none';
 83+
 84+ //show fogg stuff:
 85+ sfe = document.getElementById('fogg-video-file');
 86+ if(sfe) sfe.style.display='inline';
 87+
 88+ _this.ogg = new Firefogg();
 89+ addHandler( sfe, 'click', function(){
 90+ //add binding:
 91+ _this.select_fogg();
 92+ });
 93+ },
 94+ select_fogg:function(){
 95+ var _this = this;
 96+ if(_this.ogg.selectVideo()) {
 97+ var editForm = document.getElementById( 'mw-upload-form' );
 98+ editForm.onsubmit = function return_false(){
 99+ return false;
 100+ };
 101+ //update the submit button:
 102+
 103+ //set binding for "upload" button to call our transcode process
 104+ addHandler( editForm, 'submit', function() {
 105+ //check if the title and or description are empty don't let the person submit
 106+ e = document.getElementById('wpDestFile')
 107+ if(typeof e.value == 'undefined' || e.value=='' || e.value.substr(-4) != '.ogg')
 108+ return alert('destination file is empty or does not end with .ogg');
 109+
 110+ e = document.getElementById('wpUploadDescription')
 111+ if(typeof e.value == 'undefined' || e.value=='')
 112+ return alert('Description is empty');
 113+
 114+ //display the loader:
 115+ e = document.getElementsByClassName('dlbox-centered')
 116+ e[0].style.display='block';
 117+
 118+ e = document.getElementsByClassName('dlbox-overlay')
 119+ e[0].style.display='block';
 120+
 121+ //for some unknown reason we have to drop down the #p-search z-index:
 122+ e = document.getElementById('p-search');
 123+ if(e) e.style.zIndex = 1;
 124+
 125+
 126+ //@@todo read this from the config file rather than hard code it:
 127+ var options = JSON.stringify({'maxSize': 400, 'videoBitrate': 500});
 128+ _this.ogg.encode(options);
 129+ var encodingStatus = function() {
 130+ var status = _this.ogg.status();
 131+
 132+ //update progress bar
 133+ _this.fogg_update_progress( _this.ogg.progress() );
 134+
 135+ //loop to get new status if still encoding
 136+ if( _this.ogg.state == 'encoding' ) {
 137+ setTimeout(encodingStatus, 500);
 138+ }
 139+ //encoding sucessfull, state can also be 'encoding failed'
 140+ else if ( _this.ogg.state == 'encoding done' ) {
 141+ //hide the fogg-status-transcode
 142+ e = document.getElementById('fogg-status-transcode');
 143+ e.style.display='none';
 144+ //show the fogg-status-upload
 145+ e = document.getElementById('fogg-status-upload');
 146+ e.style.display='inline';
 147+
 148+ var data = {};
 149+
 150+ //get all the form fields:
 151+ var inputs = editForm.getElementsByTagName('input');
 152+ for(var i=0;i < inputs.length; i++){
 153+ if( inputs[i].getAttribute('name') != 'wpUploadFile'){
 154+ if( inputs[i].getAttribute('type')=='checkbox'){
 155+ if(inputs[i].checked){
 156+ data[ inputs[i].getAttribute('name') ] = 'true';
 157+ }else{
 158+ data[ inputs[i].getAttribute('name') ] = 'false';
 159+ }
 160+ }else{
 161+ data[ inputs[i].getAttribute('name') ] = inputs[i].value;
 162+ }
 163+ }
 164+ }
 165+ //hard code some values
 166+ data['wpSourceType']='file';
 167+ //get text area input:
 168+ var inputs = editForm.getElementsByTagName('textarea');
 169+ for(var i=0;i < inputs.length; i++){
 170+ data[ inputs[i].getAttribute('name') ] = inputs[i].value;
 171+ }
 172+
 173+ var data_str = JSON.stringify(data);
 174+ //alert('send data:'+ data_str);
 175+ //send to the post url:
 176+ js_log('sending to:' + editForm.action);
 177+ _this.ogg.upload(editForm.action, 'wpUploadFile', data_str);
 178+ var uploadStatus = function() {
 179+ var status = _this.ogg.status();
 180+ //js_log(' up stats: ' + status + ' p:' + _this.ogg.progress() + ' state: '+ _this.ogg.state + ' result page:' + result_page);
 181+
 182+ //update progress bar
 183+ _this.fogg_update_progress( _this.ogg.progress() );
 184+
 185+ //loop to get new status if still uploading
 186+ if(_this.ogg.state == 'uploading') {
 187+ setTimeout(uploadStatus, 500);
 188+ }
 189+ //upload sucsefull, state can also be 'upload failed'
 190+ else if(_this.ogg.state == 'upload done') {
 191+ js_log('upload done');
 192+ //@@todo handle errors same problem as #695 in mv_remote_media_search.js
 193+ //we need to add image uploading to the api rather than parse the HTML output of the pages
 194+ var result_page = JSON.parse(_this.ogg.uploadstatus()).responseText;
 195+ var sstring = 'var wgTitle = "' + data['wpDestFile'].replace('_',' ');
 196+ if( result_page.toLowerCase().indexOf( sstring.toLowerCase() ) != -1){
 197+ js_log('upload done got redirect found: ' +sstring);
 198+ if(_this.add_done_action == 'redirect'){
 199+ window.location = wgArticlePath.replace(/\$1/, 'File:' + data['wpDestFile'] );
 200+ }else{
 201+ //check if the add_done_action is a callback:
 202+ if(typeof _this.add_done_action == 'function')
 203+ _this.add_done_action();
 204+ }
 205+ }else{
 206+ js_log('upload page error: did not find: ' +sstring);
 207+ var error_txt = 'Unkown error';
 208+ sp = result_page.indexOf('<span class="error">');
 209+ if(sp!=-1){
 210+ se = result_page.indexOf('</span>', sp);
 211+ error_txt = result_page.substr(sp, (sp-se));
 212+ }else{
 213+ //look for warning:
 214+ sp = result_page.indexOf('<ul class="warning">')
 215+ if(sp!=-1){
 216+ se = result_page.indexOf('</ul>', sp);
 217+ error_txt = result_page.substr(sp, (sp-se));
 218+ }
 219+ }
 220+ e = document.getElementById('dlbox-centered');
 221+ if(e)
 222+ e.innerHTML = '<h3>Error:</h3>' + error_txt;
 223+ }
 224+ }
 225+ //upload error:
 226+ else{
 227+ alert('upload error: ' + _this.ogg.state);
 228+ }
 229+ }
 230+ uploadStatus();
 231+ }else if(_this.ogg.state == 'encoding fail'){
 232+ //@@todo error handling:
 233+ alert('encoding failed');
 234+ }
 235+ }
 236+ encodingStatus();
 237+ //don't submit the form (let firefogg hanndle it)
 238+ return false;
 239+ }); //addHandler mapping
 240+ }else{
 241+ //remove upload bidning if no file was selected
 242+ }
 243+ },
 244+ disable_fogg:function(){
 245+ //show normal file upload
 246+ e = document.getElementById('wg-base-upload');
 247+ if(e) e.style.display='inline';
 248+
 249+ //hide fogg stuff
 250+ e = document.getElementById('fogg-video-file');
 251+ if(e) e.style.display='none';
 252+
 253+ //disable the fogg
 254+ this.enabled=false;
 255+ },
 256+ fogg_update_progress:function(progress){
 257+ var progressbar = document.getElementById('fogg-progressbar');
 258+ if(progressbar)
 259+ progressbar.style.width= parseInt(progress*100) +'%';
 260+ var progstatus = document.getElementById('fogg-pstatus');
 261+ if(progstatus)
 262+ progstatus.innerHTML = parseInt(progress*100) + '% - ';
 263+ }
 264+}
\ No newline at end of file
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/mv_remote_media_search.js
@@ -0,0 +1,1376 @@
 2+/*
 3+* a library for doing remote media searches
 4+*
 5+* initial targeted archives are:
 6+ the local wiki
 7+ wikimedia commons
 8+ metavid
 9+ and archive.org
 10+*/
 11+
 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'] = ' previus ';
 18+gMsg['upload'] = 'Upload';
 19+
 20+gMsg['rsd_layout'] = 'Layout:';
 21+gMsg['rsd_resource_edit']='Edit Resource:';
 22+
 23+var default_remote_search_options = {
 24+ 'profile':'mediawiki_edit',
 25+ 'target_id':null, //the div that will hold the search interface
 26+
 27+ 'default_provider_id':'all', //all or one of the content_providers ids
 28+
 29+ 'caret_pos':null,
 30+ 'local_wiki_api_url':null,
 31+ 'target_title':null,
 32+
 33+ 'target_textbox':null,
 34+ 'instance_name': null, //a globally accessible callback instance name
 35+ 'default_query':null, //default search query
 36+ //specific to sequence profile
 37+ 'p_seq':null,
 38+ 'cFileNS':'Image', //what is the cannonical namespace for images
 39+ //@@todo (should be able to get that from the api in the future)
 40+
 41+ 'enable_uploads':true // if we want to enable an uploads tab:
 42+}
 43+var remoteSearchDriver = function(initObj){
 44+ return this.init( initObj );
 45+}
 46+remoteSearchDriver.prototype = {
 47+ results_cleared:false,
 48+ //here we define the set of possible media content providers:
 49+ main_search_options:{
 50+ 'selprovider':{
 51+ 'title': 'Select Providers'
 52+ },
 53+ 'advanced_search':{
 54+ 'title': 'Advanced Options'
 55+ }
 56+ },
 57+ content_providers:{
 58+ /*content_providers documentation:
 59+ @enabled: whether the search provider can be selected
 60+ @checked: whether the search provideer will show up as seletable tab (todo: user prefrence)
 61+ @d: if the current cp should be displayed (only one should be the default)
 62+ @title: the title of the search provider
 63+ @desc: can use html... todo: need to localize
 64+ @api_url: the url to query against given the library type:
 65+ @lib: the search library to use corresponding to the
 66+ search object ie: 'mediaWiki' = new mediaWikiSearchSearch()
 67+ @local : if the content provider assets need to be imported or not.
 68+ */
 69+ 'this_wiki':{
 70+ 'enabled':0,
 71+ 'checked':0,
 72+ 'd' :0,
 73+ 'title' :'The Current Wiki',
 74+ 'desc' : '(should be updated with the proper text)',
 75+ 'api_url': wgScriptPath + '/api.php',
 76+ 'lib' :'mediaWiki',
 77+ 'local' :true
 78+ },
 79+ 'wiki_commons':{
 80+ 'enabled':1,
 81+ 'checked':1,
 82+ 'd' :1,
 83+ 'title' :'Wikipedia Commons',
 84+ 'desc' : 'Wikimedia Commons is a media file repository making available public domain '+
 85+ 'and freely-licensed educational media content (images, sound and video clips) to all.',
 86+ 'homepage': 'http://commons.wikimedia.org/wiki/Main_Page',
 87+ 'api_url':'http://commons.wikimedia.org/w/api.php',
 88+ 'lib' :'mediaWiki',
 89+ 'resource_prefix': 'WC_', //prefix on imported resources (not applicable if the repository is local)
 90+
 91+ //list all the domains where commons is local? or set this some other way
 92+ 'local_domains': ['wikimedia','wikipedia','wikibooks'],
 93+ //specific to wiki commons config:
 94+ 'search_title':false, //disable title search
 95+ //set up default range limit
 96+ 'offset' : 0,
 97+ 'limit' : 30
 98+ },
 99+ 'metavid':{
 100+ 'enabled':1,
 101+ 'checked':1,
 102+ 'd' :0,
 103+ 'title' :'Metavid.org',
 104+ 'homepage':'http://metavid.org',
 105+ 'desc' : 'Metavid hosts thousands of hours of US house and senate floor proceedings',
 106+ 'api_url':'http://metavid.org/w/index.php?title=Special:MvExportSearch',
 107+ 'lib' : 'metavid',
 108+ 'local' :false, //if local set to true we can use local
 109+ 'resource_prefix': 'MV_', //what prefix to use on imported resources
 110+
 111+ 'local_domains': ['metavid'], // if the domain name contains metavid
 112+ // no need to import metavid content to metavid sites
 113+
 114+ 'stream_import_key': 'mv_ogg_low_quality', // which stream to import, could be mv_ogg_high_quality
 115+ //or flash stream, see ROE xml for keys
 116+
 117+ 'remote_embed_ext': false //if running the remoteEmbed extension no need to copy local
 118+ //syntax will be [remoteEmbed:roe_url link title]
 119+ },
 120+ 'archive_org':{
 121+ 'enabled':0,
 122+ 'checked':0,
 123+ 'd' :0,
 124+ 'title' : 'Archive.org',
 125+ 'desc' : 'The Internet Archive, a digital library of cultural artifacts',
 126+ 'homepage':'http://archive.org',
 127+ 'lib' : 'archive',
 128+ 'local' : false,
 129+ 'resource_prefix': 'AO_'
 130+ }
 131+ },
 132+ //some default layout values:
 133+ thumb_width : 80,
 134+ image_edit_width : 600,
 135+ video_edit_width : 400,
 136+ insert_text_pos : 0, //insert at the start (will be overwiten by the user cursor pos)
 137+ result_display_mode : 'box', //box or list or preview
 138+
 139+ cUpLoader : null,
 140+ cEdit : null,
 141+
 142+ init:function( initObj ){
 143+ js_log('remoteSearchDriver:init');
 144+ for( var i in default_remote_search_options ) {
 145+ if( initObj[i]){
 146+ this[ i ] = initObj[i];
 147+ }else{
 148+ this[ i ] =default_remote_search_options[i];
 149+ }
 150+ }
 151+ //set up the content provider config:
 152+ if(this.cpconfig){
 153+ for(var cpc in cpconfig){
 154+ for(var cinx in this.cpconfig[cpc]){
 155+ if( this.content_providers[cpc] )
 156+ this.content_providers[ cpc ][ cinx ] = this.cpconfig[cpc][ cinx];
 157+ }
 158+ }
 159+ }
 160+
 161+ //overwrite the default query if a text selection was made:
 162+ if(this.target_textbox)
 163+ this.getTexboxSelection();
 164+
 165+ this.init_interface_html();
 166+ this.add_interface_bindings();
 167+ },
 168+ //gets the in and out points for insert position or grabs the selected text for search
 169+ getTexboxSelection:function(){
 170+ if(this.caret_pos.s && this.caret_pos.e &&
 171+ (this.caret_pos.s != this.caret_pos.e))
 172+ this.default_query = this.caret_pos.text.substring(this.caret_pos.s, this.caret_pos.e).replace(/ /g, '\xa0') || '\xa0'
 173+ },
 174+ //sets up the initial html interface
 175+ init_interface_html:function(){
 176+ var dq = (this.default_query)? this.default_query : '';
 177+ var out = '<div class="rsd_control_container" style="width:100%">' +
 178+ '<table style="width:100%;background-color:transparent;">' +
 179+ '<tr>'+
 180+ '<td style="width:110px">'+
 181+ '<h3> Media Search </h3>'+
 182+ '</td>'+
 183+ '<td style="width:190px">'+
 184+ '<input type="text" tabindex="1" value="' + dq + '" maxlength="512" id="rsd_q" name="rsd_q" '+
 185+ 'size="20" autocomplete="off"/>'+
 186+ '</td>'+
 187+ '<td style="width:115px">'+
 188+ '<input type="submit" value="' + getMsg('mv_media_search') + '" tabindex="2" '+
 189+ ' id="rms_search_button"/>'+
 190+ '</td>'+
 191+ '<td>';
 192+ //out += '<a href="#" id="mso_selprovider" >Select Providers</a><br>';
 193+
 194+ //if mediawiki_edit don't output cancel button
 195+ if( this.profile == 'mediawiki_edit'){
 196+ out += '<a href="#" id="mso_cancel" >Cancel</a><br>';
 197+ }
 198+ out += '</td>'+
 199+ '</tr>'+
 200+ '</table>';
 201+ js_log('out: ' + out);
 202+
 203+ out+='<div id="rsd_options_bar" style="display:none;width:100%;height:0px;background:#BBB">';
 204+ //set up the content provider selection div (do this first to get the default cp)
 205+ out+= '<div id="cps_options">';
 206+ for( var cp_id in this.content_providers ){
 207+ var cp = this.content_providers[cp_id];
 208+ var checked_attr = ( cp.checked ) ? 'checked':'';
 209+ out+='<div title="' + cp.title + '" '+
 210+ ' style="float:left;cursor:pointer;">'+
 211+ '<input class="mv_cps_input" type="checkbox" name="mv_cps" '+ checked_attr+'>';
 212+
 213+ out+= '<img alt="'+cp.title+'" src="' + mv_embed_path + 'skins/' + mv_skin_name + '/remote_search/' + cp_id + '_tab.png">';
 214+ out+='</div>';
 215+ }
 216+ out+='<div style="clear:both"/><a id="mso_selprovider_close" href="#">'+getMsg('close')+'</a></div>';
 217+ out+='</div>';
 218+ //close up the control container:
 219+ out+='</div>';
 220+ //search provider tabs based on "checked" and "enabled" and "combined tab"
 221+ out+='<div id="rsd_results_container">';
 222+ out+='</div>';
 223+ $j('#'+ this.target_id ).html( out );
 224+ //draw the tabs:
 225+ this.drawTabs();
 226+ //run the default search:
 227+ if(this.default_query)
 228+ this.runSearch();
 229+ },
 230+ add_interface_bindings:function(){
 231+ var _this = this;
 232+ js_log("add_interface_bindings:");
 233+ //setup for this.main_search_options:
 234+ $j('#mso_cancel').click(function(){
 235+ _this.closeAll();
 236+ });
 237+
 238+ $j('#mso_selprovider,#mso_selprovider_close').click(function(){
 239+ if($j('#rsd_options_bar:hidden').length !=0 ){
 240+ $j('#rsd_options_bar').animate({
 241+ 'height':'110px',
 242+ 'opacity':1
 243+ }, "normal");
 244+ }else{
 245+ $j('#rsd_options_bar').animate({
 246+ 'height':'0px',
 247+ 'opacity':0
 248+ }, "normal", function(){
 249+ $j(this).hide();
 250+ });
 251+ }
 252+ });
 253+ //setup binding for search provider check box:
 254+ //search button:
 255+ $j('#rms_search_button').click(function(){
 256+ _this.runSearch();
 257+ });
 258+ },
 259+ doUploadInteface:function(){
 260+ var _this = this;
 261+ mv_set_loading('#rsd_results');
 262+
 263+ //load the (firefog enhanced) upload manager:
 264+ if(!_this.cUpLoader){
 265+ mvJsLoader.doLoad( {'mvUploader': 'libAddMedia/mv_upload.js'},function(){
 266+ _this.cUpLoader = new mvUploader({
 267+ 'target_div': 'rsd_results',
 268+ 'upload_cb:': function( rTitle){
 269+ //set to loading:
 270+ mv_set_loading('#rsd_results');
 271+ //do a direct api query for resource info (to build rObj
 272+ _this.getResourceFromTitle( rTitle, function(rObj){
 273+ //call resource Edit:
 274+ _this.resourceEdit( rObj );
 275+ });
 276+ }
 277+ }
 278+ );
 279+ });
 280+ }
 281+ },
 282+ runSearch: function(){
 283+ var _this = this;
 284+ //set loading div:
 285+ mv_set_loading('#rsd_results');
 286+ //get a remote search object for each search provider and run the search
 287+ for(var cp_id in this.content_providers){
 288+ var cp = this.content_providers[ cp_id ];
 289+
 290+ //only run the search for default item (unless combined is selected)
 291+ if( !cp.d || this.disp_item == 'combined' )
 292+ continue;
 293+
 294+ //set display if unset
 295+ if(!this.disp_item)
 296+ this.disp_item = cp_id;
 297+
 298+ //check if we need to update:
 299+ if(typeof cp.sObj != 'undefined'){
 300+ if(cp.sObj.last_query == $j('#rsd_q').val() && cp.sObj.last_offset == cp.offset)
 301+ continue;
 302+ }
 303+ //else we need to run the search:
 304+ var iObj = {'cp':cp, 'rsd':this};
 305+ eval('cp.sObj = new '+cp.lib+'Search(iObj);');
 306+ if(!cp.sObj)
 307+ js_log('Error: could not find search lib for ' + cp_id);
 308+
 309+ //inherit defaults if not set:
 310+ cp.limit = (cp.limit) ? cp.limit : cp.sObj.limit;
 311+ cp.offset = (cp.offset) ? cp.offset : cp.sObj.offset;
 312+
 313+ //do search:
 314+ cp.sObj.getSearchResults();
 315+ }
 316+ this.checkResultsDone();
 317+ },
 318+ checkResultsDone: function(){
 319+ var _this = this;
 320+ var loading_done = true;
 321+ for(var cp_id in this.content_providers){
 322+ cp = this.content_providers[ cp_id ];
 323+ if(typeof cp['sObj'] != 'undefined'){
 324+ if( cp.sObj.loading )
 325+ loading_done=false;
 326+ }
 327+ }
 328+ if(loading_done){
 329+ this.drawOutputResults();
 330+ }else{
 331+ setTimeout( _this.instance_name + '.checkResultsDone()', 250);
 332+ }
 333+ },
 334+ drawTabs: function(){
 335+ var _this = this;
 336+ //add the tabs to the rsd_results container:
 337+ var o='<div class="rsd_tabs_container" style="position:absolute;top:49px;width:100%;left:12px;height:25px;">';
 338+ o+= '<ul class="rsd_cp_tabs" style="margin: 0 0 0 0;position:absolute;top:0px;padding:0;">'; //no idea why margin does not overwrite from the css
 339+ o+='<li id="rsd_tab_combined" ><img src="' + mv_embed_path + 'skins/'+mv_skin_name+ '/remote_search/combined_tab.png"></li>';
 340+ for(var cp_id in this.content_providers){
 341+ var cp = this.content_providers[cp_id];
 342+ if( cp.enabled && cp.checked){
 343+ var class_attr = (cp.d)?'class="rsd_selected"':'';
 344+ o+='<li id="rsd_tab_'+cp_id+'" ' + class_attr + '><img src="' + mv_embed_path + 'skins/' + mv_skin_name + '/remote_search/' + cp_id + '_tab.png"></li>';
 345+ }
 346+ }
 347+ //do an upload tab if enabled:
 348+ if( this.enable_uploads ){
 349+ var class_attr = ( this.disp_item =='upload' ) ? 'class="rsd_selected"':'';
 350+ o+='<li id="rsd_tab_upload" ' + class_attr + ' >'+getMsg('upload');+'</li>';
 351+ }
 352+ o+='</ul>';
 353+ o+='</div>';
 354+ //outout the resource results holder
 355+ o+='<div id="rsd_results" />';
 356+ $j('#rsd_results_container').html(o);
 357+
 358+ //setup bindings for tabs:
 359+ $j('.rsd_cp_tabs li').click(function(){
 360+ _this.selectTab( $j(this).attr('id').replace(/rsd_tab_/, '') );
 361+ });
 362+ },
 363+ //resource title
 364+ getResourceFromTitle:function( rTitle , callback){
 365+ var _this = this;
 366+ reqObj={
 367+ 'action':'query',
 368+ 'titles': _this.cFileNS + ':' + rTitle
 369+ };
 370+ do_api_req( reqObj, this.local_wiki_api_url, function(data){
 371+ //propogate the rO
 372+ var rObj = {};
 373+ });
 374+ },
 375+ //@@todo we could load the id with the content provider id to find the object faster...
 376+ getResourceFromId:function( rid ){
 377+ //strip out /res/ if preset:
 378+ rid = rid.replace(/res_/, '');
 379+ for(var cp_id in this.content_providers){
 380+ cp = this.content_providers[ cp_id ];
 381+ if( cp['sObj']){
 382+ for(var rInx in cp.sObj.resultsObj){
 383+ if(rInx == rid)
 384+ return cp.sObj.resultsObj[rInx];
 385+ };
 386+ }
 387+ }
 388+ js_log("ERROR: could not find " + rid);
 389+ return false;
 390+ },
 391+ drawOutputResults: function(){
 392+ js_log('f:drawOutputResults');
 393+ var _this = this;
 394+ var o='';
 395+ $j('#rsd_results').empty();
 396+ //output the results bar / controls
 397+ _this.setResultBarControl();
 398+
 399+ //output all the results (hide based on tab selection)
 400+ for(var cp_id in this.content_providers){
 401+ cp = this.content_providers[ cp_id ];
 402+ //output results based on display mode & input:
 403+ if(typeof cp['sObj'] != 'undefined'){
 404+ $j.each(cp.sObj.resultsObj, function(rInx, rItem){
 405+ var disp = ( cp.d ) ? '' : 'display:none;';
 406+ if( _this.result_display_mode == 'box' ){
 407+ o+='<div id="mv_result_' + rInx + '" class="mv_clip_box_result" style="' + disp + 'width:' +
 408+ _this.thumb_width + 'px;height:'+ (_this.thumb_width-20) +'px">';
 409+ o+='<img title="'+rItem.title+'" class="rsd_res_item" id="res_' + rInx +'" style="width:' + _this.thumb_width + 'px;" src="' + rItem.poster + '">';
 410+ o+='</div>';
 411+ }else if(_this.result_display_mode == 'list'){
 412+ o+='<div id="mv_result_' + rInx + '" class="mv_clip_list_result" style="' + disp + 'width:90%">';
 413+ o+='<img title="'+rItem.title+'" class="rsd_res_item" id="res_' + rInx +'" style="float:left;width:' + _this.thumb_width + 'px; padding:5px;" src="' + rItem.poster + '">';
 414+ o+= rItem.desc ;
 415+ o+='<div style="clear:both" />';
 416+ o+='</div>';
 417+ }
 418+ });
 419+ }
 420+ }
 421+ //put in the new output:
 422+ $j('#rsd_results').append( o )
 423+ //remove rss only display class if present
 424+ $j('#rsd_results .mv_rss_view_only').remove();
 425+ this.addResultBindings();
 426+ },
 427+ addResultBindings:function(){
 428+ var _this = this;
 429+ $j('.mv_clip_'+_this.result_display_mode+'_result').hover(function(){
 430+ $j(this).addClass('mv_clip_'+_this.result_display_mode+'_result_over');
 431+ },function(){
 432+ $j(this).removeClass('mv_clip_'+_this.result_display_mode+'_result_over');
 433+ });
 434+ //resource click action: (bring up the resource editor)
 435+ $j('.rsd_res_item').click(function(){
 436+ //get the resource obj:
 437+ var rObj = _this.getResourceFromId( this.id );
 438+ _this.resourceEdit( rObj );
 439+ });
 440+ },
 441+ resourceEdit:function( rObj ){
 442+ //remove any existing resource edit interface:
 443+ $j('#rsd_resource_edit').remove();
 444+ //set the media type:
 445+ if(rObj.mime.indexOf('image')!=-1){
 446+ //set width to default image_edit_width
 447+ var maxWidth = _this.image_edit_width;
 448+ var mediaType = 'image';
 449+ }else{
 450+ //set to default video size:
 451+ var maxWidth = _this.video_edit_width;
 452+ var mediaType = 'video';
 453+ }
 454+ //so that transcripts show ontop
 455+ var overflow_style = ( mediaType =='video' )?'':'overflow:auto;';
 456+ //append to the top level of model window:
 457+ $j( '#'+ _this.target_id ).append('<div id="rsd_resource_edit" '+
 458+ 'style="position:absolute;top:0px;left:0px;width:100%;height:100%;background-color:#FFF;">' +
 459+ '<h3 id="rsd_resource_title" style="margin:4px;">' + getMsg('rsd_resource_edit') + ' ' + rObj.title +'</h3>'+
 460+ '<div id="clip_edit_disp" style="position:absolute;'+overflow_style+'top:30px;left:0px;bottom:0px;'+
 461+ 'width:' + (maxWidth + 30) + 'px;" >' +
 462+ mv_get_loading_img('position:absolute;top:30px;left:30px', 'mv_img_loader') +
 463+ '</div>'+
 464+ '<div id="clip_edit_ctrl" style="position:absolute;border:solid thin blue;'+
 465+ 'top:30px;left:' + (maxWidth+30) +'px;bottom:0px;right:0px;">'+
 466+ mv_get_loading_img() +
 467+ '</div>'+
 468+ '</div>');
 469+ $j('#rsd_resource_edit').css('opacity',0);
 470+
 471+ $j('#rsd_edit_img').remove();//remove any existing rsd_edit_img
 472+
 473+ //left side holds the image right size the controls /
 474+ $j(this).clone().attr('id', 'rsd_edit_img').appendTo('#clip_edit_disp').css({
 475+ 'position':'absolute',
 476+ 'top':'40%',
 477+ 'left':'20%',
 478+ 'opacity':0
 479+ });
 480+
 481+ //assume we keep aspect ratio for the thumbnail that we clicked:
 482+ var tRatio = $j(this).height() / $j(this).width();
 483+ if( ! tRatio )
 484+ var tRatio = 1; //set ratio to 1 if the width of the thumbnail can't be found for some reason
 485+
 486+ js_log('set from ' + $j('#rsd_edit_img').width()+'x'+ $j('#rsd_edit_img').height() + ' to init thumbimage to ' + maxWidth + ' x ' + parseInt( tRatio * maxWidth) );
 487+ //scale up image and swap with high res version
 488+ $j('#rsd_edit_img').animate({
 489+ 'opacity':1,
 490+ 'top':'0px',
 491+ 'left':'0px',
 492+ 'width': maxWidth + 'px',
 493+ 'height': parseInt( tRatio * maxWidth) + 'px'
 494+ }, "slow"); // do it slow to give it a chance to finish loading the HQ version
 495+
 496+ _this.loadHQImg(rObj, {'width':maxWidth}, 'rsd_edit_img', function(){
 497+ $j('.mv_img_loader').remove();
 498+ });
 499+ //also fade in the container:
 500+ $j('#rsd_resource_edit').animate({
 501+ 'opacity':1,
 502+ 'background-color':'#FFF',
 503+ 'z-index':99
 504+ });
 505+ _this.doMediaEdit( rObj , mediaType );
 506+ },
 507+ loadHQImg:function(rObj, size, target_img_id, callback){
 508+ //get the HQ image url:
 509+ rObj.pSobj.getImageObj( rObj, size, function( imObj ){
 510+ rObj['url'] = imObj.url;
 511+
 512+ //update the rObj
 513+ rObj['org_width'] = imObj.org_width;
 514+ rObj['width'] = imObj.width;
 515+ rObj['height'] = imObj.height;
 516+
 517+ //see if we need to animate some transition
 518+ var newSize = false;
 519+ if( size.width != imObj.width ){
 520+ js_log('loadHQImg:size mismatch: ' + size.width + ' != ' + imObj.width );
 521+ newSize={
 522+ 'width':imObj.width + 'px',
 523+ 'height':imObj.height + 'px'
 524+ }
 525+ //set the target id to the new size:
 526+ $j('#'+target_img_id).animate( newSize );
 527+ }else{
 528+ js_log('using req size: ' + imObj.width + 'x' + imObj.height);
 529+ $j('#'+target_img_id).animate( {'width':imObj.width+'px', 'height' : imObj.height + 'px'});
 530+ }
 531+ //don't swap it in until its loaded:
 532+ var img = new Image();
 533+ // load the image image:
 534+ $j(img).load(function () {
 535+ $j('#'+target_img_id).attr('src', imObj.url);
 536+ //let the caller know we are done and what size we ended up with:
 537+ callback();
 538+ }).error(function () {
 539+ js_log("Error with: " + imObj.url);
 540+ }).attr('src', imObj.url);
 541+ });
 542+ },
 543+ //loads the media editor:
 544+ doMediaEdit:function( rObj , mediaType){
 545+ var _this = this;
 546+ var mvClipInit = {
 547+ 'rObj':rObj, //the resource object
 548+ 'parent_ct':'rsd_resource_edit',
 549+ 'clip_disp_ct':'clip_edit_disp',
 550+ 'control_ct': 'clip_edit_ctrl',
 551+ 'media_type': mediaType,
 552+ 'p_rsdObj': _this
 553+ };
 554+ var loadLibs = {'mvClipEdit':'libSequencer/mv_clipedit.js'};
 555+ if( mediaType == 'image'){
 556+ //load the croping library:
 557+ loadLibs['$j.Jcrop']='jquery/plugins/Jcrop/js/jquery.Jcrop.js';
 558+ //@@todo integrate css calls into mvJsLoader or move jcrop css
 559+ loadExternalCss( mv_embed_path + 'jquery/plugins/Jcrop/css/jquery.Jcrop.css');
 560+ //display the mvClipEdit obj once we are done loading:
 561+ mvJsLoader.doLoad( loadLibs,function(){
 562+ //run the image clip tools
 563+ _this.cEdit = new mvClipEdit( mvClipInit );
 564+ });
 565+ }
 566+ if( mediaType == 'video'){
 567+ js_log('append html: ' + rObj.pSobj.getEmbedHTML( rObj, {id:'embed_vid'}) );
 568+ $j('#clip_edit_disp').append(
 569+ rObj.pSobj.getEmbedHTML( rObj, {id:'embed_vid'})
 570+ );
 571+ //rewrite by id handldes getting any libs we are missing:
 572+ rewrite_by_id('embed_vid',function(){
 573+ //grab any information that we got from the ROE xml or parsed from the media file
 574+ rObj = rObj.pSobj.getEmbedObjParsedInfo(rObj, 'embed_vid');
 575+ //add the re-sizable to the doLoad request:
 576+ loadLibs['$j.ui.resizable'] = 'jquery/jquery.ui-1.5.2/ui/minified/ui.resizable.min.js',
 577+ loadLibs['$j.fn.hoverIntent'] = 'jquery/plugins/jquery.hoverIntent.js';
 578+ mvJsLoader.doLoad( loadLibs,function(){
 579+ //run the image clip tools
 580+ _this.cEdit = new mvClipEdit( mvClipInit );
 581+ });
 582+ });
 583+ }
 584+ },
 585+ checkImportResource:function( rObj, cir_callback){
 586+ //@@todo get the localized File/Image namespace name or do a general {NS}:Title aproch
 587+ var cp = rObj.pSobj.cp;
 588+ var _this = this;
 589+ rObj.target_resource_title = rObj.titleKey.replace(/File:|Image:/,'');
 590+
 591+ //check if we can embed the content locally per a domain name check:
 592+ var local_embed_ref=false;
 593+ var local_host = parseUri(this.local_wiki_api_url).host;
 594+ if( rObj.pSobj.cp.local_domains ) {
 595+ for(var i=0;i < rObj.pSobj.cp.local_domains.length; i++){
 596+ var ld = rObj.pSobj.cp.local_domains[i];
 597+ if( local_host.indexOf( ld ) != -1)
 598+ local_embed_ref=true;
 599+ }
 600+ }
 601+ //locally embeddalbe jump to callback:
 602+ if( local_embed_ref ){
 603+ cir_callback( rObj );
 604+ }else{
 605+ //not a local domain update target resource name with the prefix:
 606+ rObj.target_resource_title = cp.resource_prefix +rObj.target_resource_title;
 607+
 608+ //check if the resource is not already on this wiki
 609+ reqObj={'action':'query', 'titles': _this.cFileNS + ':' + rObj.target_resource_title};
 610+
 611+ do_api_req( reqObj, this.local_wiki_api_url, function(data){
 612+ var found_title = false;
 613+ for(var i in data.query.pages){
 614+ if( i != '-1' && i != '-2' ){
 615+ js_log('found title: ' + i + ':' + data.query.pages[i]['title']);
 616+ found_title=data.query.pages[i]['title'];
 617+ }
 618+ }
 619+ if( found_title ){
 620+ js_log("checkImportResource:found title:" + found_title);
 621+ //resource is already present (or resource with same name is already present)
 622+ rObj.target_resource_title = found_title.replace(/File:|Image:/,'');
 623+ cir_callback( rObj );
 624+ }else{
 625+ js_log("resource not present: update:"+ _this.cFileNS + ':' + rObj.target_resource_title);
 626+
 627+ //update the rObj with import info
 628+ rObj.pSobj.updateDataForImport( rObj );
 629+
 630+ //setup the resource description from resource description:
 631+ var base_resource_desc = '{{Information '+"\n"+
 632+ '|Description= ' + rObj.title + ' imported from ' + '[' + cp.homepage +
 633+ ' ' + cp.title+']' + "\n" +
 634+ '|Source=' + '[' + rObj.link.replace(/^\s\s*/, '').replace(/\s\s*$/, '') +' Original Source]'+ "\n";
 635+
 636+ if( rObj.author )
 637+ base_resource_desc+='|Author= ' + rObj.author +"\n";
 638+
 639+ if( rObj.date )
 640+ base_resource_desc+='|Date=' + rObj.date +"\n";
 641+
 642+ if( rObj.permission )
 643+ base_resource_desc+='|Permission='+ rObj.permission +"\n";
 644+
 645+ if( rObj.other_versions )
 646+ base_resource_desc+='|Other_versions=' + rObj.other_versions + "\n";
 647+
 648+ base_resource_desc+='}}';
 649+
 650+ //add in licence template tag:
 651+ if( rObj.licence_template_tag )
 652+ base_resource_desc += "\n" +
 653+ '== [[Commons:Copyright tags|Licensing]]: ==' +"\n"+
 654+ '{{' + rObj.licence_template_tag + '}}';
 655+
 656+ $j('#rsd_resource_import').remove();//remove any old resource imports
 657+ //@@ show user dialog to import the resource
 658+ $j( '#'+ _this.target_id ).append('<div id="rsd_resource_import" '+
 659+ 'style="position:absolute;top:50px;left:50px;right:50px;bottom:50px;background-color:#FFF;border:solid thick red;z-index:3">' +
 660+ '<h3 style="color:red">Resource: <span style="color:black">' + rObj.title + '</span> needs to be imported</h3>'+
 661+ '<div id="rsd_preview_import_container" style="position:absolute;width:50%;bottom:0px;left:0px;overflow:auto;top:30px;">' +
 662+ rObj.pSobj.getEmbedHTML( rObj, {'max_height':'200','only_poster':true} )+ //get embedHTML with small thumb:
 663+ '<br style="clear both">'+
 664+ '<strong>Resource Page Description:</strong>'+
 665+ '<div id="rsd_import_desc" syle="display:inline;">'+
 666+ mv_get_loading_img('position:absolute;top:5px;left:5px', 'mv_img_loader') +
 667+ '</div>'+
 668+ '</div>'+
 669+ '<div id="rds_edit_import_container" style="position:absolute;left:50%;' +
 670+ 'bottom:0px;top:30px;right:0px;overflow:auto;">'+
 671+ '<strong>Local Resource Title:</strong><br>'+
 672+ '<input type="text" size="30" value="' + rObj.target_resource_title + '" readonly="true"><br>'+
 673+ '<strong>Edit WikiText Resource Description:</strong>(will be replaced by forms soon)'+
 674+ '<textarea id="rsd_import_ta" id="mv_img_desc" style="width:90%;" rows="8" cols="50">'+
 675+ base_resource_desc +
 676+ '</textarea><br>'+
 677+ '<input type="checkbox" value="true" id="wpWatchthis" name="wpWatchthis" tabindex="7"/>'+
 678+ '<label for="wpWatchthis">Watch this page</label><br>'+
 679+ '<input id="rsd_import_apreview" type="button" value="Update Preview"> ' +
 680+ '<input style="font-weight: bold" id="rsd_import_doimport" type="button" value="Do Import Resource"> '+
 681+ '<a id="rsd_import_acancel" href="#">Cancel Import</a>'+
 682+ '</div>'+
 683+ //output the rendered and non-renderd version of description for easy swiching:
 684+ '</div>');
 685+ //load the preview text:
 686+ _this.getParsedWikiText( base_resource_desc, _this.cFileNS +':'+ rObj.target_resource_title, function( o ){
 687+ $j('#rsd_import_desc').html(o);
 688+ });
 689+ //add bidings:
 690+ $j('#rsd_import_apreview').click(function(){
 691+ $j('#rsd_import_desc').show().html(
 692+ mv_get_loading_img()
 693+ );
 694+ //load the preview text:
 695+ _this.getParsedWikiText( $j('#rsd_import_ta').val(), _this.cFileNS +':'+ rObj.target_resource_title, function( o ){
 696+ js_log('got updated preivew: '+ o);
 697+ $j('#rsd_import_desc').html(o);
 698+ });
 699+ });
 700+ $j('#rsd_import_doimport').click(function(){
 701+ //replace the parent with progress bar:
 702+ $j('#rsd_resource_import').html(
 703+ '<h3>Importing asset</h3>'+
 704+ mv_get_loading_img()
 705+ );
 706+ //get an edittoken:
 707+ var reqObj = {'action':'query','prop':'info','intoken':'edit','titles': rObj.titleKey };
 708+ do_api_req( reqObj, _this.local_wiki_api_url, function(data){
 709+ //could recheck if it has been created in the mean time
 710+ if( data.query.pages[-1] ){
 711+ var editToken = data.query.pages[-1]['edittoken'];
 712+ if(!editToken){
 713+ //@@todo give an ajax login or be more friendly in some way:
 714+ js_error("You don't have permission to upload (are you logged in?)");
 715+ //remove top level:
 716+ $j('#modalbox').fadeOut("normal",function(){
 717+ $j(this).remove();
 718+ $j('#mv_overlay').remove();
 719+ });
 720+ }else{
 721+ //not sure if we can do remote url uploads (so just do a local post)
 722+ js_log('got token for new page:' +editToken);
 723+ var postVars = {
 724+ 'wpSourceType' :'web',
 725+ 'wpUploadFileURL' : rObj.url,
 726+ 'wpDestFile' : rObj.target_resource_title,
 727+ 'wpUploadDescription':$j('#rsd_import_ta').val(),
 728+ 'wpWatchthis' : $j('#wpWatchthis').val(),
 729+ 'wpUpload' : 'Upload file'
 730+ }
 731+ //set to uploading:
 732+ $j('#rsd_resource_import').append('<div id="rsd_import_progress"'+
 733+ 'style="position:absolute;top:0px;'+
 734+ 'left:0px;width:100%;height:100%;'+
 735+ 'z-index:5;background:#FFF;overflow:auto;">'+
 736+ '<div style="position:absolute;left:30%;right:30%"><h3>Importing Asset</h3><br>' +
 737+ mv_get_loading_img('','mv_loading_bar_img') +
 738+ '</div>'+
 739+ '</div>'
 740+ );
 741+ $j.post(wgArticlePath.replace(/\$1/,'Special:Upload'),
 742+ postVars,
 743+ function(data){
 744+ //@@todo this will be replaced once we add upload image support to the api.
 745+
 746+ //very basic test to see if we got passed to the image page:
 747+ //@@todo more normalization stuff
 748+ var sstring ='var wgPageName = "' + _this.cFileNS + ':' + rObj.target_resource_title.replace(/ /g,'_') +'"';
 749+ if(data.indexOf( sstring ) !=-1){
 750+ js_log('found: ' + sstring);
 751+ $j('#rsd_resource_import').remove();
 752+ cir_callback( rObj );
 753+ }else{
 754+ js_log("Error or warning: (did not find: \"" + sstring + ' in output' );
 755+ pos_etitle = '<h1 class="firstHeading">';
 756+ var error_txt='';
 757+ if(data.indexOf(pos_etitle)!=-1){
 758+ var sp = data.indexOf(pos_etitle) + pos_etitle.length;
 759+ error_txt = data.substr(sp ,
 760+ (data.indexOf('</h1>',sp )-sp)
 761+ );
 762+ }
 763+ //var error_msg =
 764+ $j('#rsd_resource_import').html(
 765+ '<b>error importing asset (we should have better error handling soon)</b><br>'+
 766+ error_txt + '<br>'+
 767+ '<a href="#" id="rsd_import_error" >Cancel import</a>'
 768+ );
 769+ $j('#rsd_import_error').click(function(){
 770+ $j('#rsd_resource_import').remove();
 771+ });
 772+ }
 773+
 774+ }
 775+ );
 776+ }
 777+ }
 778+ });
 779+
 780+ });
 781+ $j('#rsd_import_acancel').click(function(){
 782+ $j('#rsd_resource_import').fadeOut("fast",function(){
 783+ $j(this).remove();
 784+ })
 785+ })
 786+ }
 787+ });
 788+ }
 789+ },
 790+ previewResource:function( rObj ){
 791+ var _this = this;
 792+ this.checkImportResource( rObj, function(){
 793+ //put another window ontop:
 794+ $j( '#'+ _this.target_id ).append('<div id="rsd_resource_preview" '+
 795+ 'style="position:absolute;z-index:4;top:0px;left:0px;width:100%;height:100%;background-color:#FFF;">' +
 796+ '<h3>preview insert of resource: ' + rObj.title + '</h3>'+
 797+ '<div id="rsd_preview_display" style="position:absolute;width:100%;top:30px;bottom:30px;overflow:auto;">' +
 798+ mv_get_loading_img('top:30px;left:30px') +
 799+ '</div>' +
 800+ '<div id="rsd_preview_control" style="position:absolute;width:60%;left:40%;bottom:0px;height:30px;">' +
 801+ '<input type="button" id="preview_do_insert" value="Do Insert">' +
 802+ '<a href="#" id="preview_close">Do More Modification</a>' +
 803+ '</div>' +
 804+ '</div>');
 805+ //update the preview_wtext
 806+ _this.updatePreviewText( rObj );
 807+
 808+ _this.getParsedWikiText(_this.preview_wtext, _this.target_title,
 809+ function(phtml){
 810+ $j('#rsd_preview_display').html( phtml );
 811+ }
 812+ );
 813+ //add bindings:
 814+ $j('#preview_do_insert').click(function(){
 815+ _this.insertResource( rObj );
 816+ });
 817+ $j('#preview_close').click(function(){
 818+ $j('#rsd_resource_preview').remove();
 819+ });
 820+ });
 821+ },
 822+ updatePreviewText:function( rObj ){
 823+ var _this = this;
 824+ //insert at start if textInput cursor has not been set (ie == length)
 825+ if( _this.caret_pos.text.length == _this.caret_pos.s)
 826+ _this.caret_pos.s=0;
 827+ _this.preview_wtext = _this.caret_pos.text.substring(0, _this.caret_pos.s) +
 828+ rObj.pSobj.getEmbedWikiText( rObj ) +
 829+ _this.caret_pos.text.substring( _this.caret_pos.s );
 830+ },
 831+ getParsedWikiText:function( wikitext, title, callback ){
 832+ var reqObj = {
 833+ 'action':'parse',
 834+ 'text':wikitext
 835+ };
 836+ do_api_req( reqObj, this.local_wiki_api_url, function(data){
 837+ callback( data.parse.text['*'] );
 838+ });
 839+ },
 840+ insertResource:function( rObj){
 841+ var _this = this
 842+ this.checkImportResource( rObj, function(){
 843+ _this.updatePreviewText( rObj );
 844+ $j('#'+_this.target_textbox).val( _this.preview_wtext );
 845+ _this.closeAll();
 846+ });
 847+ },
 848+ closeAll:function( rObj ){
 849+ $j('#modalbox').fadeOut("normal",function(){
 850+ $j(this).remove();
 851+ $j('#mv_overlay').remove();
 852+ });
 853+ },
 854+ setResultBarControl:function( ){
 855+ var _this = this;
 856+ var box_dark_url = mv_embed_path + 'skins/' + mv_skin_name + '/images/box_layout_icon_dark.png';
 857+ var box_light_url = mv_embed_path + 'skins/' + mv_skin_name + '/images/box_layout_icon.png';
 858+ var list_dark_url = mv_embed_path + 'skins/' + mv_skin_name + '/images/list_layout_icon_dark.png';
 859+ var list_light_url = mv_embed_path + 'skins/' + mv_skin_name + '/images/list_layout_icon.png';
 860+
 861+
 862+ $j('#rsd_results').append('<div id="rds_results_bar">'+
 863+ '<span style="position:relative;top:-5px;font-style:italic;">'+
 864+ getMsg('rsd_layout')+' '+
 865+ '</span>'+
 866+ '<img id="msc_box_layout" ' +
 867+ 'title = "' + getMsg('rsd_box_layout') + '" '+
 868+ 'src = "' + ( (_this.result_display_mode=='box')?box_dark_url:box_light_url ) + '" ' +
 869+ 'style="width:20px;height:20px;cursor:pointer;"> ' +
 870+ '<img id="msc_list_layout" '+
 871+ 'title = "' + getMsg('rsd_list_layout') + '" '+
 872+ 'src = "' + ( (_this.result_display_mode=='list')?list_dark_url:list_light_url ) + '" '+
 873+ 'style="width:20px;height:20px;cursor:pointer;">'+
 874+ '<span id="rsd_paging_ctrl" style="position:absolute;right:5px;"></span>'+
 875+ '</div>'
 876+ );
 877+ //get paging with bindings:
 878+ this.getPaging('#rsd_paging_ctrl');
 879+
 880+ $j('#msc_box_layout').hover(function(){
 881+ $j(this).attr("src", box_dark_url );
 882+ }, function(){
 883+ $j(this).attr("src", ( (_this.result_display_mode=='box')?box_dark_url:box_light_url ) );
 884+ }).click(function(){
 885+ $j(this).attr("src", box_dark_url);
 886+ $j('#msc_list_layout').attr("src", list_light_url);
 887+ _this.setDispMode('box');
 888+ });
 889+
 890+ $j('#msc_list_layout').hover(function(){
 891+ $j(this).attr("src", list_dark_url);
 892+ }, function(){
 893+ $j(this).attr("src", ( (_this.result_display_mode=='list')?list_dark_url:list_light_url ) );
 894+ }).click(function(){
 895+ $j(this).attr("src", list_dark_url);
 896+ $j('#msc_box_layout').attr("src", box_light_url);
 897+ _this.setDispMode('list');
 898+ });
 899+ },
 900+ getPaging:function(target){
 901+ var _this = this;
 902+ //if more than one repository displayed (disable paging)
 903+ if(this.disp_item == 'combined'){
 904+ $j(target).html('no paging for combined results');
 905+ return ;
 906+ }
 907+ for(var cp_id in this.content_providers){
 908+ var cp = this.content_providers[ cp_id ];
 909+ if(this.disp_item == cp_id){
 910+ js_log('getPaging:'+ cp_id);
 911+ var out = getMsg('rsd_results_desc') + (cp.offset+1) + ' to ' + (cp.offset + cp.limit);
 912+ //check if we have more results (next prev link)
 913+ if( cp.offset >= cp.limit )
 914+ out+=' <a href="#" id="rsd_pprev">' + getMsg('rsd_results_prev') + cp.limit + '</a>';
 915+ if( cp.sObj.more_results )
 916+ out+=' <a href="#" id="rsd_pnext">' + getMsg('rsd_results_next') + cp.limit + '</a>';
 917+ $j(target).html(out);
 918+ //set bindings
 919+ $j('#rsd_pnext').click(function(){
 920+ cp.offset += cp.limit;
 921+ _this.runSearch();
 922+ });
 923+ $j('#rsd_pprev').click(function(){
 924+ cp.offset -= cp.limit;
 925+ if(cp.offset<0)
 926+ cp.offset=0;
 927+ _this.runSearch();
 928+ });
 929+
 930+ return;
 931+ }
 932+ }
 933+
 934+ },
 935+ selectTab:function( selected_cp_id ){
 936+ js_log('select tab: ' + selected_cp_id);
 937+ this.disp_item = selected_cp_id;
 938+ //set display to unselected:
 939+ for(var cp_id in this.content_providers){
 940+ cp = this.content_providers[ cp_id ];
 941+ if( (selected_cp_id == 'combined' && cp.checked ) || selected_cp_id == cp_id){
 942+ cp.d = 1;
 943+ }else{
 944+ cp.d = 0;
 945+ }
 946+ }
 947+ //redraw tabs
 948+ this.drawTabs();
 949+
 950+ if( this.disp_item == 'upload' ){
 951+ this.doUploadInteface();
 952+ }else{
 953+ //update the search results:
 954+ this.runSearch();
 955+ }
 956+ },
 957+ setDispMode:function(mode){
 958+ js_log('setDispMode:' + mode);
 959+ this.result_display_mode=mode;
 960+ //run /update search display:
 961+ this.drawOutputResults();
 962+ }
 963+}
 964+//default values:
 965+// tag_name@{attribute}
 966+var rsd_default_rss_item_mapping = {
 967+ 'poster' : 'media:thumbnail@url',
 968+ 'roe_url' : 'media:roe_embed@url',
 969+ 'title' : 'title',
 970+ 'link' : 'link',
 971+ 'desc' : 'description'
 972+}
 973+var mvBaseRemoteSearch = function(initObj) {
 974+ return this.init(initObj);
 975+};
 976+mvBaseRemoteSearch.prototype = {
 977+
 978+ completed_req:0,
 979+ num_req:0,
 980+
 981+ resultsObj:{},
 982+
 983+ //default search result values for paging:
 984+ offset :0,
 985+ limit :20,
 986+ more_results :false,
 987+ num_results :null,
 988+
 989+ //init the object:
 990+ init:function( initObj ){
 991+ js_log('mvBaseRemoteSearch:init');
 992+ for(var i in initObj){
 993+ this[i] = initObj[i];
 994+ }
 995+ return this;
 996+ },
 997+ /*
 998+ * Parses and adds video rss based input format
 999+ * @data XML data to parse
 1000+ * @provider_url the source url (used to generate absolute links)
 1001+ */
 1002+ addRSSData:function( data , provider_url ){
 1003+ var _this = this;
 1004+ var http_host = '';
 1005+ var http_path = '';
 1006+ if(provider_url){
 1007+ pUrl = parseUri( provider_url );
 1008+ http_host = pUrl.protocol +'://'+ pUrl.authority;
 1009+ http_path = pUrl.directory;
 1010+ }
 1011+ items = data.getElementsByTagName('item');
 1012+ $j.each(data.getElementsByTagName('item'), function(inx, item){
 1013+ var rObj ={};
 1014+ for(var i in rsd_default_rss_item_mapping){
 1015+ var selector = rsd_default_rss_item_mapping[i].split('@');
 1016+
 1017+ var tag_name = selector[0];
 1018+ var attr_name = null;
 1019+
 1020+ if( selector[1] )
 1021+ attr_name = selector[1];
 1022+
 1023+ //grab the first match
 1024+ var node = item.getElementsByTagName( tag_name )[0];
 1025+ //js_log('node: ' + node + ' nv:' + $j(node).html() + ' nv[0]'+ node.innerHTML +
 1026+ //' cn' + node.childNodes[0].nodeValue );
 1027+
 1028+ if( node!=null && attr_name == null ){
 1029+ if( node.childNodes[0] != null){
 1030+ rObj[i] = node.textContent;
 1031+ }
 1032+ }
 1033+
 1034+ if( node!=null && attr_name != null)
 1035+ rObj[i] = $j(node).attr( attr_name );
 1036+ }
 1037+ //make relative urls absolute:
 1038+ var url_param = new Array('src', 'poster');
 1039+ for(var j=0; j < url_param.length; j++){
 1040+ var p = url_param[j];
 1041+ if(typeof rObj[p] != 'undefined'){
 1042+ if( rObj[p].substr(0,1)=='/' ){
 1043+ rObj[p] = http_host + rObj[p];
 1044+ }
 1045+ if( parseUri( rObj[i] ).host == rObj[p]){
 1046+ rObj[p] = http_host + http_path + rObj[p];
 1047+ }
 1048+ }
 1049+ }
 1050+ //force a mime type for now.. in the future generalize for other RSS feeds
 1051+ rObj['mime'] = 'video/ogg';
 1052+ //add pointer to parent search obj:( this.cp.limit )? this.cp.limit : this.limit,
 1053+
 1054+ rObj['pSobj'] = _this;
 1055+ //add the result to the result set:
 1056+ _this.resultsObj[inx] = rObj;
 1057+ });
 1058+ },
 1059+ //by default just return the existing image:
 1060+ getImageObj:function( rObj, size, callback){
 1061+ callback( {'url':rObj.poster} );
 1062+ },
 1063+ getEmbedObjParsedInfo:function(rObj, eb_id){
 1064+ return rObj;
 1065+ },
 1066+ getEmbedWikiText:function(rObj){
 1067+ var layout = ( rObj.layout)? rObj.layout:"right"
 1068+ var o= '[[' + this.rsd.cFileNS + ':' + rObj.target_resource_title + '|thumb|'+layout;
 1069+
 1070+ if(rObj.target_width)
 1071+ o+='|' + rObj.target_width + 'px';
 1072+
 1073+ if( rObj.inlineDesc )
 1074+ o+='|' + rObj.inlineDesc;
 1075+
 1076+ o+=']]';
 1077+ return o;
 1078+ },
 1079+ updateDataForImport:function( rObj ){
 1080+ return rObj;
 1081+ }
 1082+}
 1083+/*
 1084+* api modes (implementations should call these objects which inherit the mvBaseRemoteSearch
 1085+*/
 1086+var metavidSearch = function(initObj) {
 1087+ return this.init(initObj);
 1088+};
 1089+metavidSearch.prototype = {
 1090+ reqObj:{ //set up the default request paramaters
 1091+ 'order':'recent',
 1092+ 'feed_format':'rss'
 1093+ },
 1094+ init:function( initObj ){
 1095+ //init base class and inherit:
 1096+ var baseSearch = new mvBaseRemoteSearch( initObj );
 1097+ for(var i in baseSearch){
 1098+ if(typeof this[i] =='undefined'){
 1099+ this[i] = baseSearch[i];
 1100+ }else{
 1101+ this['parent_'+i] = baseSearch[i];
 1102+ }
 1103+ }
 1104+ },
 1105+ getSearchResults:function(){
 1106+ var _this = this;
 1107+ //start loading:
 1108+ _this.loading= 1;
 1109+ js_log('metavidSearch::getSearchResults()');
 1110+ //proccess all options
 1111+ var url = this.cp.api_url;
 1112+ //add on the req_param
 1113+ for(var i in this.reqObj){
 1114+ url += '&' + i + '=' + this.reqObj[i];
 1115+ }
 1116+ //do basic query:
 1117+ this.last_query = $j('#rsd_q').val();
 1118+ this.last_offset = cp.offset;
 1119+ url += '&f[0][t]=match&f[0][v]=' + $j('#rsd_q').val();
 1120+ //add offset limit:
 1121+ url+='&limit=' + this.cp.limit;
 1122+ url+='&offset=' + this.cp.offset;
 1123+
 1124+ do_request(url, function(data){
 1125+ //should have an xml rss data object:
 1126+ _this.addRSSData( data , url );
 1127+ //do some metavid specific pos processing on the rObj data:
 1128+ for(var i in _this.resultsObj){
 1129+ var rObj = _this.resultsObj[i];
 1130+ var proe = parseUri( rObj['roe_url'] );
 1131+ rObj['start_time'] = proe.queryKey['t'].split('/')[0];
 1132+ rObj['end_time'] = proe.queryKey['t'].split('/')[1];
 1133+ rObj['stream_name'] = proe.queryKey['stream_name'];
 1134+ //transform the title into a wiki_safe title:
 1135+ //rObj['titleKey'] = proe.queryKey['stream_name'] + '_' + rObj['start_time'].replace(/:/g,'.') + '_' + rObj['end_time'].replace(/:/g,'.') + '.ogg';
 1136+ rObj['titleKey'] = proe.queryKey['stream_name'] + '/' + rObj['start_time'] + '/' + rObj['end_time'] + '__.ogg';
 1137+ }
 1138+ //done loading:
 1139+ _this.loading=0;
 1140+ });
 1141+ },
 1142+ getEmbedWikiText:function(rObj, options){
 1143+ //if we are using a local copy do the standard b:
 1144+ if( this.cp.local_copy == true)
 1145+ return this.parent_getEmbedWikiText(rObj, options);
 1146+ //if local_copy is false and embed metavid extension is enabled:
 1147+ return
 1148+ },
 1149+ getEmbedHTML:function( rObj , options ){
 1150+ var id_attr = (options['id'])?' id = "' + options['id'] +'" ': '';
 1151+ var style_attr = (options['max_width'])?' style="width:'+options['max_width']+'px;"':'';
 1152+ if(options['only_poster']){
 1153+ return '<img ' + id_attr + ' src="' + rObj['poster']+'" ' + style_attr + '>';
 1154+ }else{
 1155+ return '<video ' + id_attr + ' roe="' + rObj['roe_url'] + '"></video>';
 1156+ }
 1157+ },
 1158+ getEmbedObjParsedInfo:function(rObj, eb_id){
 1159+ var sources = $j('#'+eb_id).get(0).media_element.getSources();
 1160+ rObj.other_versions ='*[' + rObj['roe_url'] + ' XML of all Video Formats and Timed Text]'+"\n";
 1161+ for(var i in sources){
 1162+ var cur_source = sources[i];
 1163+ //rObj.other_versions += '*['+cur_source.getURI() +' ' + cur_source.title +']' + "\n";
 1164+ if( cur_source.id == this.cp.target_source_id)
 1165+ rObj['url'] = cur_source.getURI();
 1166+ }
 1167+ js_log('set url to: ' + rObj['url']);
 1168+ return rObj;
 1169+ },
 1170+ //update rObj for import:
 1171+ updateDataForImport:function( rObj ){
 1172+ rObj['author']='US Government';
 1173+ //convert data to UTC type date:
 1174+ var dateExp = new RegExp(/_([0-9]+)\-([0-9]+)\-([0-9]+)/);
 1175+ var dParts = rObj.link.match (dateExp);
 1176+ var d = new Date();
 1177+ var year_full = (dParts[3].length==2)?'20'+dParts[3].toString():dParts[3];
 1178+ d.setFullYear(year_full, dParts[1]-1, dParts[2]);
 1179+ rObj['date'] = d.toDateString();
 1180+ rObj['licence_template_tag']='PD-USGov';
 1181+ //update based on new start time:
 1182+ js_log('url is: ' + rObj.src + ' ns: ' + rObj.start_time + ' ne:' + rObj.end_time);
 1183+
 1184+ return rObj;
 1185+ }
 1186+}
 1187+
 1188+var mediaWikiSearch = function( initObj ) {
 1189+ return this.init( initObj );
 1190+};
 1191+mediaWikiSearch.prototype = {
 1192+ init:function( initObj ){
 1193+ //init base class and inherit:
 1194+ var baseSearch = new mvBaseRemoteSearch( initObj );
 1195+ for(var i in baseSearch){
 1196+ if(typeof this[i] =='undefined'){
 1197+ this[i] = baseSearch[i];
 1198+ }else{
 1199+ this['parent_'+i] = baseSearch[i];
 1200+ }
 1201+ }
 1202+ //inherit the cp settings for
 1203+ },
 1204+ getSearchResults:function(){
 1205+ var _this = this;
 1206+ this.loading=true;
 1207+ js_log('f:getSearchResults for:' + $j('#'+this.target_input).val() );
 1208+ //empty out the current results:
 1209+ this.resultsObj={};
 1210+ //do two queries against the Image / File / MVD namespace:
 1211+
 1212+ //build the image request object:
 1213+ var reqObj = {
 1214+ 'action':'query',
 1215+ 'generator':'search',
 1216+ 'gsrsearch': encodeURIComponent( $j('#rsd_q').val() ),
 1217+ 'gsrnamespace':6, //(only search the "file" namespace (audio, video, images)
 1218+ 'gsrwhat':'title',
 1219+ 'gsrlimit': this.cp.limit,
 1220+ 'gsroffset': this.cp.offset,
 1221+ 'prop':'imageinfo|revisions|categories',
 1222+ 'iiprop':'url|mime',
 1223+ 'iiurlwidth': parseInt( this.rsd.thumb_width ),
 1224+ 'rvprop':'content'
 1225+ };
 1226+ //set up the number of request:
 1227+ this.completed_req=0;
 1228+ this.num_req=1;
 1229+ this.last_query = $j('#rsd_q').val();
 1230+ //setup the number of requests result flag:
 1231+ //do_api_req( reqObj, this.cp.api_url , function(data){
 1232+ //parse the return data
 1233+ // _this.addResults( data);
 1234+ // _this.checkRequestDone();
 1235+ //});
 1236+ //also do a request for page titles (would be nice if api could query both at the same time)
 1237+ reqObj['gsrwhat']='text';
 1238+ do_api_req( reqObj, this.cp.api_url , function(data){
 1239+ //parse the return data
 1240+ _this.addResults( data);
 1241+ //_this.checkRequestDone(); //only need if we do two queries one for title one for text
 1242+ _this.loading = false;
 1243+ });
 1244+ },
 1245+ addResults:function( data ){
 1246+ var _this = this
 1247+ //check if we have
 1248+ if( typeof data['query-continue'].search != 'undefined')
 1249+ this.more_results = true;
 1250+ //make sure we have pages to iderate:
 1251+ if(data.query && data.query.pages){
 1252+ for(var page_id in data.query.pages){
 1253+ var page = data.query.pages[ page_id ];
 1254+ //make sure the page is not a redirect
 1255+ if(page.revisions[0]['*'].indexOf('#REDIRECT')===0){
 1256+ //skip page is redirect
 1257+ continue;
 1258+ }
 1259+
 1260+ this.resultsObj[page_id]={
 1261+ 'titleKey':page.title,
 1262+ 'link':page.imageinfo[0].descriptionurl,
 1263+ 'title':page.title.replace(/File:|.jpg|.png|.svg|.ogg|.ogv/ig, ''),
 1264+ 'poster':page.imageinfo[0].thumburl,
 1265+ 'thumbwidth':page.imageinfo[0].thumbwidth,
 1266+ 'thumbheight':page.imageinfo[0].thumbheight,
 1267+ 'mime':page.imageinfo[0].mime,
 1268+ 'src':page.imageinfo[0].url,
 1269+ 'desc':page.revisions[0]['*'],
 1270+ //add pointer to parent serach obj:
 1271+ 'pSobj':_this,
 1272+ 'meta':{
 1273+ 'categories':page.categories
 1274+ }
 1275+ }
 1276+ //for(var i in this.resultsObj[page_id]){
 1277+ // js_log('added '+ i +' '+ this.resultsObj[page_id][i]);
 1278+ //}
 1279+ }
 1280+ }else{
 1281+ js_log('no results:' + data);
 1282+ }
 1283+ },
 1284+ //check request done used for when we have multiple requests to check before formating results.
 1285+ checkRequestDone:function(){
 1286+ //display output if done:
 1287+ this.completed_req++;
 1288+ if(this.completed_req == this.num_req){
 1289+ this.loading = 0;
 1290+ }
 1291+ },
 1292+ getImageObj:function( rObj, size, callback ){
 1293+ if( rObj.mime=='application/ogg' )
 1294+ return callback( {'url':rObj.src, 'poster' : rObj.url } );
 1295+
 1296+ //build the query to get the req size image:
 1297+ var reqObj = {
 1298+ 'action':'query',
 1299+ 'titles':rObj.titleKey,
 1300+ 'prop':'imageinfo',
 1301+ 'iiprop':'url|size|mime'
 1302+ }
 1303+ //set the width:
 1304+ if(size.width)
 1305+ reqObj['iiurlwidth']= size.width;
 1306+
 1307+ do_api_req( reqObj, this.cp.api_url , function(data){
 1308+ var imObj = {};
 1309+ for(var page_id in data.query.pages){
 1310+ var iminfo = data.query.pages[ page_id ].imageinfo[0];
 1311+ //store the orginal width:
 1312+ imObj['org_width']=iminfo.width;
 1313+ //check if thumb size > than image size and is jpeg or png (it will not scale well above its max res)
 1314+ if( ( iminfo.mime=='image/jpeg' || iminfo=='image/png' ) &&
 1315+ iminfo.thumbwidth > iminfo.width ){
 1316+ imObj['url'] = iminfo.url;
 1317+ imObj['width'] = iminfo.width;
 1318+ imObj['height'] = iminfo.height;
 1319+ }else{
 1320+ imObj['url'] = iminfo.thumburl;
 1321+ imObj['width'] = iminfo.thumbwidth;
 1322+ imObj['height'] = iminfo.thumbheight;
 1323+ }
 1324+ }
 1325+ js_log('getImageObj: get: ' + size.width + ' got url:' + imObj.url);
 1326+ callback( imObj );
 1327+ });
 1328+ },
 1329+ //the insert image function
 1330+ insertImage:function( cEdit ){
 1331+ if(!cEdit)
 1332+ var cEdit = _this.cEdit;
 1333+ },
 1334+ getEmbedHTML: function( rObj , options) {
 1335+ //set up the output var with the default values:
 1336+ var outOpt = { 'width': rObj.width, 'height': rObj.height};
 1337+ if( options['max_height'] ){
 1338+ outOpt.height = (options.max_height > rObj.height) ? rObj.height : options.max_height;
 1339+ outOpt.width = (rObj.width / rObj.height) *outOpt.height;
 1340+ }
 1341+ var style_attr = 'style="width:' + outOpt.width + 'px;height:' + outOpt.height +'px"';
 1342+ var id_attr = (options['id'])?' id = "' + options['id'] +'" ': '';
 1343+
 1344+ //return the html type:
 1345+ if(rObj.mime.indexOf('image')!=-1){
 1346+ return '<img ' + id_attr + ' src="' + rObj.url + '"' + style_attr + ' >';
 1347+ }
 1348+ if(rObj.mime.indexOf('application/ogg')!=-1){
 1349+ return '<video ' + id_attr +
 1350+ ' src="' + rObj.src + '" ' +
 1351+ style_attr +
 1352+ ' poster="'+ outOpt.url + '" '+
 1353+ ' ></video>';
 1354+ }
 1355+ js_log('ERROR:unsupored mime type: ' + rObj.mime);
 1356+ },
 1357+ //returns the inline wikitext for insertion (template based crops for now)
 1358+ getEmbedWikiText: function( rObj ){
 1359+ //set default layout to right justified
 1360+ var layout = ( rObj.layout)? rObj.layout:"right"
 1361+ //if crop is null do base output:
 1362+ if( rObj.crop == null)
 1363+ return this.parent_getEmbedWikiText( rObj );
 1364+ //using the preview crop template: http://en.wikipedia.org/wiki/Template:Preview_Crop
 1365+ //@@todo should be replaced with server side cropping
 1366+ return '{{Preview Crop ' + "\n" +
 1367+ '|Image = ' + rObj.target_resource_title + "\n" +
 1368+ '|bSize = ' + rObj.width + "\n" +
 1369+ '|cWidth = ' + rObj.crop.w + "\n" +
 1370+ '|cHeight = ' + rObj.crop.h + "\n" +
 1371+ '|oTop = ' + rObj.crop.y + "\n" +
 1372+ '|oLeft = ' + rObj.crop.x + "\n" +
 1373+ '|Location =' + layout + "\n" +
 1374+ '|Description =' + rObj.inlineDesc + "\n" +
 1375+ '}}';
 1376+ }
 1377+}
\ No newline at end of file
Property changes on: trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/mv_remote_media_search.js
___________________________________________________________________
Name: svn:mergeinfo
11378 +
Name: svn:eol-style
21379 + native
Property changes on: trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia
___________________________________________________________________
Name: svn:mergeinfo
31380 +
Index: trunk/extensions/MetavidWiki/skins/mv_embed/libSequencer/mv_sequencer.js
@@ -132,7 +132,7 @@
133133 'html': getMsg('loading_txt'),
134134 'js':function( this_seq ){
135135 //load the search interface with sequence tool targets
136 - mvJsLoader.doLoad({'remoteSearchDriver':'libRemoteMediaSearch/mv_remote_media_search.js'}, function(){
 136+ mvJsLoader.doLoad({'remoteSearchDriver':'libAddMedia/mv_remote_media_search.js'}, function(){
137137 this_seq.mySearch = new remoteSearchDriver({
138138 'profile':'sequence',
139139 'p_seq':this_seq,
Index: trunk/extensions/MetavidWiki/skins/mv_embed/skins/mvpcf/styles.css
@@ -513,10 +513,9 @@
514514 ul.rsd_cp_tabs li {
515515 display:inline;
516516 margin:0;
517 - padding:10px 0 0;
 517+ padding:10px 2px 10px 2px;
518518 background:#F7F7F7 url(remote_search/tab-bg.png) repeat-x scroll left bottom;
519 - border:1px solid #777;
520 - padding-bottom:10px;
 519+ border:1px solid #777;
521520 margin-left:7px;
522521 cursor:pointer;
523522 }
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_embed.js
@@ -138,6 +138,13 @@
139139 var class_attr = (class_attr)?'class="'+class_attr+'"':'class="mv_loading_img"';
140140 return '<div '+class_attr+' style="' + style +'"></div>';
141141 }
 142+function mv_set_loading(target, load_id){
 143+ var id_attr = ( load_id )?' id="' + load_id + '" ':'';
 144+ $j(target).append('<div '+id_attr+' style="position:absolute;top:0px;left:0px;height:100%;width:100%;'+
 145+ 'background-color:#FFF;">' +
 146+ mv_get_loading_img('top:30px;left:30px') +
 147+ '</div>');
 148+}
142149
143150 /* the base video control JSON object with default attributes
144151 * for supported attribute details see README
@@ -1097,7 +1104,7 @@
10981105 mvEmbed.load_libs(function(){
10991106 //load search specifc extra stuff
11001107 mvJsLoader.doLoad({
1101 - 'mvBaseRemoteSearch':'libRemoteMediaSearch/mv_remote_media_search.js'
 1108+ 'mvBaseRemoteSearch':'libAddMedia/mv_remote_media_search.js'
11021109 }, function(){
11031110 initObj['instance_name']= 'rsdMVRS';
11041111 rsdMVRS = new remoteSearchDriver( initObj );
@@ -3172,12 +3179,12 @@
31733180 */
31743181 /*var log_elm = document.getElementById('mv_js_log');
31753182 if(!log_elm){
3176 - document.write('<div style="position:absolute;z-index:500;top:0px;left:0px;right:0px;height:150px;"><textarea id="mv_js_log" cols="80" rows="6"></textarea></div>');
 3183+ document.write('<div style="position:absolute;z-index:500;top:0px;left:0px;right:0px;height:50px;"><textarea id="mv_js_log" cols="80" rows="2"></textarea></div>');
31773184 var log_elm = document.getElementById('mv_js_log');
31783185 }
31793186 if(log_elm){
31803187 log_elm.value+=string+"\n";
3181 - }*/
 3188+ }*/
31823189 }
31833190 //return false;
31843191 }

Status & tagging log