From a84b2ad7bb99f7c600217c6e18b3a0188a6fa6fb Mon Sep 17 00:00:00 2001 From: Michael Dale Date: Sat, 14 Nov 2009 17:11:28 +0000 Subject: [PATCH] * baseRemoteSearch :: addRSSData re-factoring * some comment updates * started to re-factor metavid api queries in an effort to depreciate do_request * language msg updates * import resource is no longer "red" * fixed playing of stream offsets presentation time onDone action * refactored global xml parsing into the mw object --- js2/mwEmbed/libAddMedia/remoteSearchDriver.js | 27 ++--- .../searchLibs/baseRemoteSearch.js | 106 +++++++++--------- .../libAddMedia/searchLibs/flickrSearch.js | 2 +- .../libAddMedia/searchLibs/metavidSearch.js | 59 ++++++---- js2/mwEmbed/libEmbedVideo/embedVideo.js | 10 +- js2/mwEmbed/libTimedText/mvTextInterface.js | 4 +- js2/mwEmbed/mv_embed.js | 66 ++++++----- js2/mwEmbed/skins/mvpcf/playerSkin.css | 10 +- 8 files changed, 160 insertions(+), 124 deletions(-) diff --git a/js2/mwEmbed/libAddMedia/remoteSearchDriver.js b/js2/mwEmbed/libAddMedia/remoteSearchDriver.js index 4b229a6a3a..457c9ecb8c 100644 --- a/js2/mwEmbed/libAddMedia/remoteSearchDriver.js +++ b/js2/mwEmbed/libAddMedia/remoteSearchDriver.js @@ -39,7 +39,7 @@ loadGM( { "mwe-local_resource_title" : "Local resource title:", "mwe-watch_this_page" : "Watch this page", "mwe-do_import_resource" : "Import resource", - "mwe-update_preview" : "Update preview", + "mwe-update_preview" : "Update resource page preview", "mwe-cancel_import" : "Cancel import", "mwe-importing_asset" : "Importing asset", "mwe-preview_insert_resource" : "Preview insert of resource: $1", @@ -209,8 +209,8 @@ remoteSearchDriver.prototype = { 'api_url':'http://www.flickr.com/services/rest/', 'lib' : 'flickr', 'local' : false, - // resources from fliker don't have a human parsable identifier/title - 'resource_prefix': '', + // Just prefix with Flickr_ for now. + 'resource_prefix': 'Flickr_', 'tab_img':true }, 'metavid': { @@ -254,6 +254,10 @@ remoteSearchDriver.prototype = { init: function( options ) { var _this = this; js_log( 'remoteSearchDriver:init' ); + //add in a local "id" refrence top each cp: + for(var cp_id in this.content_providers){ + this.content_providers[ cp_id ].id = cp_id; + } // merge in the options: // @@todo for cleaner config we should set _this.opt to the provided options) @@ -1082,7 +1086,6 @@ remoteSearchDriver.prototype = { 'style="position:absolute;top:0px;left:0px;bottom:0px;right:4px;background-color:#FFF;">' + '
' + - mv_get_loading_img() + '
' + '
' + '

' + gM( 'mwe-resource-needs-import', [rObj.title, _this.upload_api_name] ) + '

' + '
' + @@ -1447,6 +1450,7 @@ remoteSearchDriver.prototype = { '
' + '' + '


' + + $j.btnHtml( gM( 'mwe-update_preview' ), 'rsd_import_apreview', 'refresh' ) + ' ' + '
' + // output the rendered and non-rendered version of description for easy switching: '
' ); @@ -1454,11 +1458,8 @@ remoteSearchDriver.prototype = { $j( bPlaneTarget ).html ( // add the btns to the bottom: $j.btnHtml( gM( 'mwe-do_import_resource' ), 'rsd_import_doimport', 'check' ) + ' ' + - - $j.btnHtml( gM( 'mwe-update_preview' ), 'rsd_import_apreview', 'refresh' ) + ' ' + - $j.btnHtml( gM( 'mwe-cancel_import' ), 'rsd_import_acancel', 'close' ) + ' ' - ).addClass( 'ui-state-error' ); + ); // add hover: @@ -1471,8 +1472,8 @@ remoteSearchDriver.prototype = { $j( '#rsd_import_desc' ).html( o ); } ); // add bindings: - $j( bPlaneTarget + ' .rsd_import_apreview' ).btnBind().click( function() { - js_log( "do preview asset" ); + $j( _this.target_container + ' .rsd_import_apreview' ).btnBind().click( function() { + js_log( " Do preview asset update" ); $j( '#rsd_import_desc' ).html( mv_get_loading_img() ); // load the preview text: _this.getParsedWikiText( $j( '#rsd_import_ta' ).val(), _this.cFileNS + ':' + rObj.target_resource_title, function( o ) { @@ -1505,7 +1506,7 @@ remoteSearchDriver.prototype = { } ); }, /** - * sets up the proxy for the remote inserts + * Sets up the proxy for the remote inserts */ setupProxy:function( callback ) { var _this = this; @@ -1515,7 +1516,7 @@ remoteSearchDriver.prototype = { callback(); return ; } - // setup the the proxy via mv_embed $j.apiProxy loader: + // setup the the proxy via $j.apiProxy loader: if ( ! _this.upload_api_proxy_frame ) { js_log( "Error:: remote api but no proxy frame target" ); return false; diff --git a/js2/mwEmbed/libAddMedia/searchLibs/baseRemoteSearch.js b/js2/mwEmbed/libAddMedia/searchLibs/baseRemoteSearch.js index 92bc29f57d..65e8255649 100644 --- a/js2/mwEmbed/libAddMedia/searchLibs/baseRemoteSearch.js +++ b/js2/mwEmbed/libAddMedia/searchLibs/baseRemoteSearch.js @@ -7,8 +7,9 @@ loadGM( { // @value is where to find the value in the item xml // // *format:* -// . indicates multiple tags @ seperates the tag from attribute list +// . indicates multiple tags @ separates the tag from attribute list // {.}tag_name@{attribute1|attribute12} + // @@todo should probably switch this over to something like Xpath if we end up parsing a lot of rss formats var rsd_default_rss_item_mapping = { 'poster' : 'media:thumbnail@url', @@ -73,57 +74,11 @@ baseRemoteSearch.prototype = { } var items = data.getElementsByTagName( 'item' ); // js_log('found ' + items.length ); - $j.each( items, function( inx, item ) { + $j.each( items, function( inx, item ) { var rObj = { }; - for ( var i in rsd_default_rss_item_mapping ) { - var selector = rsd_default_rss_item_mapping[i].split( '@' ); - - var flag_multiple = ( selector[0].substr( 0, 1 ) == '.' ) ? true : false; - if ( flag_multiple ) { - rObj[i] = new Array(); - var tag_name = selector[0].substr( 1 ); - } else { - var tag_name = selector[0]; - } - - var attr_name = null; - if ( typeof selector[1] != 'undefined' ) { - attr_name = selector[1]; - if ( attr_name.indexOf( '|' ) != - 1 ) - attr_name = attr_name.split( '|' ); - } - - $j.each( item.getElementsByTagName( tag_name ), function ( inx, node ) { - var tag_val = ''; - if ( node != null && attr_name == null ) { - if ( node.childNodes[0] != null ) { - // trim and strip html: - tag_val = $j.trim( node.firstChild.nodeValue ).replace(/(<([^>]+)>)/ig,""); - } - } - if ( node != null && attr_name != null ) { - if ( typeof attr_name == 'string' ) { - tag_val = $j.trim( $j( node ).attr( attr_name ) ); - } else { - var attr_vals = { }; - for ( var j in attr_name ) { - if ( $j( node ).attr( attr_name[j] ).length != 0 ) - attr_vals[ attr_name[j] ] = $j.trim( $j(node).attr( attr_name[j]) ).replace(/(<([^>]+)>)/ig,""); - } - tag_val = attr_vals ; - } - } - if ( flag_multiple ) { - rObj[i].push( tag_val ) - } else { - rObj[i] = tag_val; - } - } ); - - - } // done with property loop - - + for ( var attr in rsd_default_rss_item_mapping ) { + _this.mapAttributeToResource( rObj, item, attr ); + } // make relative urls absolute: var url_param = new Array( 'src', 'poster' ); for ( var j = 0; j < url_param.length; j++ ) { @@ -147,6 +102,51 @@ baseRemoteSearch.prototype = { _this.num_results++; } ); }, + mapAttributeToResource: function(rObj, item, attr){ + var selector = rsd_default_rss_item_mapping[ attr ].split( '@' ); + var flag_multiple = ( selector[0].substr( 0, 1 ) == '.' ) ? true : false; + if ( flag_multiple ) { + rObj[ attr ] = new Array(); + var tag_name = selector[0].substr( 1 ); + } else { + var tag_name = selector[0]; + } + + var attr_name = null; + if ( typeof selector[1] != 'undefined' ) { + attr_name = selector[1]; + if ( attr_name.indexOf( '|' ) != - 1 ) + attr_name = attr_name.split( '|' ); + } + + $j.each( item.getElementsByTagName( tag_name ), function ( inx, node ) { + var tag_val = ''; + if ( node != null && attr_name == null ) { + if ( node.childNodes[0] != null ) { + // trim and strip html: + tag_val = $j.trim( node.firstChild.nodeValue ).replace(/(<([^>]+)>)/ig,""); + } + } + if ( node != null && attr_name != null ) { + if ( typeof attr_name == 'string' ) { + tag_val = $j.trim( $j( node ).attr( attr_name ) ); + } else { + var attr_vals = { }; + for ( var j in attr_name ) { + if ( $j( node ).attr( attr_name[j] ).length != 0 ) + attr_vals[ attr_name[j] ] = $j.trim( $j(node).attr( attr_name[j]) ).replace(/(<([^>]+)>)/ig,""); + } + tag_val = attr_vals ; + } + } + if ( flag_multiple ) { + rObj[ attr ].push( tag_val ) + } else { + rObj[ attr ] = tag_val; + } + } ); + // Nothing to return we update the "rObj" directly + }, getEmbedHTML: function( rObj , options ) { if ( !options ) options = { }; @@ -203,13 +203,13 @@ baseRemoteSearch.prototype = { }, getImportResourceDescWiki:function( rObj ) { - return gM( 'mwe-imported_from', [rObj.title, this.cp.homepage, this.cp.title, rObj.link] ); + return gM( 'mwe-imported_from', [rObj.title, this.cp.homepage, gM('rsd-' + this.cp.id + '-title'), rObj.link] ); }, // for thigns like categories and the like getExtraResourceDescWiki:function( rObj ) { return ''; }, - // by default just return the poster (clients can overide) + // by default just return the poster (clients can override) getImageTransform:function( rObj, opt ) { return rObj.poster; }, diff --git a/js2/mwEmbed/libAddMedia/searchLibs/flickrSearch.js b/js2/mwEmbed/libAddMedia/searchLibs/flickrSearch.js index eb320c9f6d..a752ef5a33 100644 --- a/js2/mwEmbed/libAddMedia/searchLibs/flickrSearch.js +++ b/js2/mwEmbed/libAddMedia/searchLibs/flickrSearch.js @@ -3,7 +3,7 @@ * http://www.flickr.com/services/api/ * * uses the "example api_key" 519b66e3fd8d8080e27a64fe51101e2c -* should update with a difrent "public" key sometime soon +* should update with a different "public" key sometime soon http://www.flickr.com/services/rest/?method=flickr.test.echo&format=json&api_key=519b66e3fd8d8080e27a64fe51101e2c * * we look for licenses from method=flickr.photos.licenses.getInfo diff --git a/js2/mwEmbed/libAddMedia/searchLibs/metavidSearch.js b/js2/mwEmbed/libAddMedia/searchLibs/metavidSearch.js index c32009939c..2f141d8894 100644 --- a/js2/mwEmbed/libAddMedia/searchLibs/metavidSearch.js +++ b/js2/mwEmbed/libAddMedia/searchLibs/metavidSearch.js @@ -8,9 +8,10 @@ var metavidSearch = function( iObj ) { return this.init( iObj ); }; metavidSearch.prototype = { - reqObj: { // set up the default request paramaters + defaultReq: { // set up the default request paramaters 'order':'recent', - 'feed_format':'rss' + 'feed_format':'json_rss', + 'cb_inx': 1 // Not really used (we should update the metavid json retrun system) }, init:function( iObj ) { // init base class and inherit: @@ -29,24 +30,34 @@ metavidSearch.prototype = { // set local ref: var _this = this; js_log( 'metavidSearch::getSearchResults()' ); - // proccess all options + // Proccess all options var url = this.cp.api_url; - // add on the req_param - for ( var i in this.reqObj ) { - url += '&' + i + '=' + this.reqObj[i]; - } - url += '&f[0][t]=match&f[0][v]=' + $j( '#rsd_q' ).val(); + var reqObj = $j.extend({}, this.defaultReq); + reqObj[ 'f[0][t]' ] = 'match'; + reqObj[ 'f[0][v]' ] = $j( '#rsd_q' ).val(); + // add offset limit: - url += '&limit=' + this.cp.limit; - url += '&offset=' + this.cp.offset; - - do_request( url, function( data ) { + reqObj[ 'limit' ] = this.cp.limit; + reqObj[ 'offset' ] = this.cp.offset; - js_log( 'mvSearch: got data response' ); - // should have an xml rss data object: - _this.addRSSData( data , url ); - - // do some metavid specific pos processing on the rObj data: + do_api_req({ + 'url' : url, + 'jsonCB' : 'cb', + 'data' : reqObj + }, function( data ) { + js_log( 'mvSearch: got data response::' ); + var xmldata = ( data && data['pay_load'] ) ? mw.parseXML( data['pay_load'] ) : false; + if( !xmldata ){ + // XML Error or No results: + _this.resultsObj = {}; + _this.loading = 0; + return ; + } + + // Add the data xml payload with context url: + _this.addRSSData( xmldata , url ); + + // Do some metavid specific pos processing on the rObj data: for ( var i in _this.resultsObj ) { var rObj = _this.resultsObj[i]; var proe = mw.parseUri( rObj['roe_url'] ); @@ -54,25 +65,27 @@ metavidSearch.prototype = { rObj['end_time'] = proe.queryKey['t'].split( '/' )[1]; rObj['stream_name'] = proe.queryKey['stream_name']; - // all metavid content is public domain: + // All metavid content is public domain: rObj['license'] = _this.rsd.getLicenceFromKey( 'pd' ); - // transform the title into a wiki_safe title: - // rObj['titleKey'] = proe.queryKey['stream_name'] + '_' + rObj['start_time'].replace(/:/g,'.') + '_' + rObj['end_time'].replace(/:/g,'.') + '.ogg'; + // Transform the title into a wiki_safe title: rObj['titleKey'] = _this.getTitleKey( rObj ); - // default width of metavid clips: + // Default width of metavid clips: rObj['target_width'] = 400; } // done loading: _this.loading = 0; } ); }, + /** + * Get a Title key for the assset name inside the mediaWiki system + */ getTitleKey:function( rObj ) { - return rObj['stream_name'] + '_part_' + rObj['start_time'].replace(/:/ g, '.' ) + '_to_' + rObj['end_time'].replace(/:/g, '.' ) + '.ogv'; + return rObj['stream_name'] + '_part_' + rObj['start_time'].replace(/:/g, '.' ) + '_to_' + rObj['end_time'].replace(/:/g, '.' ) + '.ogv'; }, getTitle:function( rObj ) { - var sn = rObj['stream_name'].replace( /_/ g, ' ' ); + var sn = rObj['stream_name'].replace( /_/g, ' ' ); sn = sn.charAt( 0 ).toUpperCase() + sn.substr( 1 ); return gM( 'mwe-stream_title', [ sn, rObj.start_time, rObj.end_time ] ); }, diff --git a/js2/mwEmbed/libEmbedVideo/embedVideo.js b/js2/mwEmbed/libEmbedVideo/embedVideo.js index f0c0b8d716..9fd50ac6c6 100644 --- a/js2/mwEmbed/libEmbedVideo/embedVideo.js +++ b/js2/mwEmbed/libEmbedVideo/embedVideo.js @@ -917,9 +917,8 @@ embedVideo.prototype = { if ( this.roe && this.media_element.sources.length == 0 ) { js_log( 'loading external data' ); this.loading_external_data = true; - var _this = this; - do_request( this.roe, function( data ) - { + var _this = this; + do_request( this.roe, function( data ){ // Continue _this.media_element.addROE( data ); js_log( 'added_roe::' + _this.media_element.sources.length ); @@ -2126,8 +2125,9 @@ embedVideo.prototype = { } } // Check if we are "done" - if ( this.currentTime > ( parseInt( this.duration ) + 1 ) ) { - js_log( "should run clip done ct:: " + this.currentTime + ' > ' + parseInt( this.duration + 1 ) ); + var end_presentation_time = parseFloat( this.startOffset) + parseFloat( this.duration ) ; + if ( this.currentTime > end_presentation_time ) { + js_log( "should run clip done ct:: " + this.currentTime + ' > ' + end_presentation_time ); this.onClipDone(); } } else { diff --git a/js2/mwEmbed/libTimedText/mvTextInterface.js b/js2/mwEmbed/libTimedText/mvTextInterface.js index 695fe4bbed..7b9470ca5c 100644 --- a/js2/mwEmbed/libTimedText/mvTextInterface.js +++ b/js2/mwEmbed/libTimedText/mvTextInterface.js @@ -456,7 +456,9 @@ mvTextInterface.prototype = { if ( this.autoscroll ) { // start the timer if its not already running if ( !this.scrollTimerId ) { - this.scrollTimerId = setInterval( '$j(\'#' + _this.pe.id + '\').get(0).textInterface.monitor()', 500 ); + var mvElm = $j('#' + _this.id ).get(0); + if( mvElm ) + this.scrollTimerId = setInterval( mvElm.textInterface.monitor(), 500 ); } // jump to the current position: var cur_time = parseInt ( this.pe.currentTime ); diff --git a/js2/mwEmbed/mv_embed.js b/js2/mwEmbed/mv_embed.js index 9bc69c3fa6..7c7b88bd4c 100644 --- a/js2/mwEmbed/mv_embed.js +++ b/js2/mwEmbed/mv_embed.js @@ -816,7 +816,34 @@ var global_req_cb = new Array(); // The global request callback array strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ } - }; + }; + /** + * Takes in a string returns an xml dom object + */ + $.parseXML = function ( str ){ + if ( $j.browser.msie ) { + // Attempt to parse as XML for IE + var xmldata = new ActiveXObject( "Microsoft.XMLDOM" ); + xmldata.async = "false"; + try{ + xmldata.loadXML( str ); + return xmldata; + } catch (e){ + js_log( 'XML parse ERROR: ' + e.message ); + return false; + } + } + + // For others (Firefox, Safari etc, older browsers + // Some don't have native DOMParser either fallback defined bellow. + try { + var xmldata = ( new DOMParser() ).parseFromString( str, "text/xml" ); + } catch ( e ) { + js_log( 'XML parse ERROR: ' + e.message ); + return false; + } + return xmldata; + } } )( window.mw ); // Get the mv_embed location if it has not been set @@ -1630,7 +1657,7 @@ function mv_jqueryBindings() { '$j.ui.dialog' ] ], function() { - $j( '#mwe_tmp_loader' ).dialog( 'close' ); + $j( '#mwe_tmp_loader' ).dialog( 'destroy' ).remove(); } ); } @@ -1788,7 +1815,7 @@ function do_api_req( options, callback ) { // js_log('do api req: ' + options.url +'?' + jQuery.param(options.data) ); if ( options.url == 'proxy' && mw.proxy ) { // assume the proxy is already "setup" since mw.proxy is defined. - // @@todo we probably integrate that setup into the api call + // @@todo should probably integrate that setup into the api call mw.proxy.doRequest( options.data, callback ); } else if ( mw.parseUri( document.URL ).host == mw.parseUri( options.url ).host ) { // Local request: do API request directly @@ -1824,13 +1851,15 @@ function do_api_req( options, callback ) { loadExternalJs( req_url ); } } -// Do a "normal" request +// Do a request: +// @@note this contains metavid specific local vs remote api remapping. +// this should be depreciated and we should use "$j.get" or an explicate api call +// (we should not mix the two request types) function do_request( req_url, callback ) { - js_log( 'do_request::req_url:' + req_url + ' != ' + mw.parseUri( req_url ).host ); + js_log( 'do_request::req_url:' + mw.parseUri( document.URL ) + ' != ' + mw.parseUri( req_url ).host ); // If we are doing a request to the same domain or relative link, do a normal GET if ( mw.parseUri( document.URL ).host == mw.parseUri( req_url ).host || - req_url.indexOf( '://' ) == - 1 ) // Relative url - { + req_url.indexOf( '://' ) == -1 ){ // if its a relative url go directly as well // Do a direct request $j.ajax( { type: "GET", @@ -1843,10 +1872,9 @@ function do_request( req_url, callback ) { } else { // Get data via DOM injection with callback global_req_cb.push( callback ); - // Prepend json_ to feed_format if not already requesting json format (metavid specific) + // Prepend json_ to feed_format if not already requesting json format (metavid specific) if ( req_url.indexOf( "feed_format=" ) != - 1 && req_url.indexOf( "feed_format=json" ) == - 1 ) - req_url = req_url.replace( / feed_format = / , 'feed_format=json_' ); - + req_url = req_url.replace( /feed_format=/, 'feed_format=json_' ); loadExternalJs( req_url + '&cb=mv_jsdata_cb&cb_inx=' + ( global_req_cb.length - 1 ) ); } } @@ -1867,23 +1895,7 @@ function mv_jsdata_cb( response ) { break; case 'text/xml': if ( typeof response['pay_load'] == 'string' ) { - // js_log('load string:'+"\n"+ response['pay_load']); - // Debugger; - if ( $j.browser.msie ) { - // Attempt to parse as XML for IE - var xmldata = new ActiveXObject( "Microsoft.XMLDOM" ); - xmldata.async = "false"; - xmldata.loadXML( response['pay_load'] ); - } else { - // For others (Firefox, Safari etc.) - try { - var xmldata = ( new DOMParser() ).parseFromString( response['pay_load'], "text/xml" ); - } catch ( e ) { - js_log( 'XML parse ERROR: ' + e.message ); - } - } - // @@todo handle XML parser errors - if ( xmldata )response['pay_load'] = xmldata; + response['pay_load'] = mw.parseXML( response['pay_load'] ); } break default: diff --git a/js2/mwEmbed/skins/mvpcf/playerSkin.css b/js2/mwEmbed/skins/mvpcf/playerSkin.css index 0583fd3338..1a51a1c64c 100644 --- a/js2/mwEmbed/skins/mvpcf/playerSkin.css +++ b/js2/mwEmbed/skins/mvpcf/playerSkin.css @@ -3,7 +3,15 @@ */ /* large play button: */ -.mv-player .play-btn-large { width:130px; height:96px; background: url(images/player_big_play_button.png) !important; position:absolute; cursor:pointer; border:none !important; }/*.ui-state-default */ +.mv-player .play-btn-large { + width:130px; + height:96px; + background: url(images/player_big_play_button.png) !important; + position:absolute; + cursor:pointer; + border:none !important; + z-index:1; +}/*.ui-state-default */ .mv-player -- 2.20.1