2 * Base remote search Object.
3 * provides the base class for the other search system to extend.
6 "mwe-imported_from" : "$1 imported from [$2 $3]. See the original [$4 resource page] for more information.",
7 "mwe-import-description" : "$1, imported from $2"
11 * rsd_default_rss_item_mapping
13 * @key is name of rObj variable
14 * @value is where to find the value in the item xml
17 * . indicates multiple tags
18 * @ separates the tag from attribute list
19 * {.}tag_name@{attribute1|attribute2}
21 * Also see mapAttributeToResource function bellow
23 * FIXME should switch this over to something like Xpath if we end up parsing a lot of rss formats
25 var rsd_default_rss_item_mapping = {
26 'poster' : 'media:thumbnail@url',
27 'roe_url' : 'media:roe_embed@url',
28 'person' : 'media:person@label|url',
29 'parent_clip':'media:parent_clip@url',
30 'bill' : 'media:bill@label|url',
33 'desc' : 'description',
35 'category' : '.media:category@label|url'
38 var baseRemoteSearch = function( iObj ) {
39 return this.init( iObj );
41 baseRemoteSearch.prototype = {
46 // ResultsObj holds the array of results
49 // Default search result values for paging:
56 * Initialise the baseRemoteSearch
57 * @param {Object} options The set of options for the remote search class
59 init: function( options ) {
60 js_log( 'mvBaseRemoteSearch:init' );
61 for ( var i in options ) {
66 getSearchResults:function() {
67 // Empty out the current results before issuing a request
68 this.resultsObj = { };
70 // Do global getSearchResults bindings
71 this.last_query = $j( '#rsd_q' ).val();
72 this.last_offset = this.cp.offset;
74 // Set the loading flag:
78 * Parses and adds video rss based input format
79 * @param {XML Nodes} data the data to be parsed
80 * @param {String} provider_url the source url (used to generate absolute links)
82 addRSSData:function( data , provider_url ) {
83 js_log( 'f:addRSSData' );
88 pUrl = mw.parseUri( provider_url );
89 http_host = pUrl.protocol + '://' + pUrl.authority;
90 http_path = pUrl.directory;
92 var items = data.getElementsByTagName( 'item' );
93 // js_log('found ' + items.length );
94 $j.each( items, function( inx, item ) {
96 for ( var attr in rsd_default_rss_item_mapping ) {
97 _this.mapAttributeToResource( rObj, item, attr );
99 // make relative urls absolute:
100 var url_param = new Array( 'src', 'poster' );
101 for ( var j = 0; j < url_param.length; j++ ) {
102 var p = url_param[j];
103 if ( typeof rObj[p] != 'undefined' ) {
104 if ( rObj[p].substr( 0, 1 ) == '/' ) {
105 rObj[p] = http_host + rObj[p];
107 if ( mw.parseUri( rObj[i] ).host == rObj[p] ) {
108 rObj[p] = http_host + http_path + rObj[p];
112 // Force a mime type. In the future generalize for other RSS feeds
113 rObj['mime'] = 'video/ogg';
114 // Add pointer to parent search obj:( this.cp.limit )? this.cp.limit : this.limit,
116 rObj['pSobj'] = _this;
117 // add the result to the result set:
118 _this.resultsObj[ inx ] = rObj;
123 * Maps a given attribute to a resource object per mapping defined in
124 * rsd_default_rss_item_mapping
126 * @param {Object} rObj the resource object
127 * @param {XML Node} the xml result node
128 * @param {attr} the name attribute we are maping to the resource object
130 mapAttributeToResource: function( rObj, item, attr ){
131 var selector = rsd_default_rss_item_mapping[ attr ].split( '@' );
132 var flag_multiple = ( selector[0].substr( 0, 1 ) == '.' ) ? true : false;
133 if ( flag_multiple ) {
134 rObj[ attr ] = new Array();
135 var tag_name = selector[0].substr( 1 );
137 var tag_name = selector[0];
140 var attr_name = null;
141 if ( typeof selector[1] != 'undefined' ) {
142 attr_name = selector[1];
143 if ( attr_name.indexOf( '|' ) != -1 )
144 attr_name = attr_name.split( '|' );
147 $j.each( item.getElementsByTagName( tag_name ), function ( inx, node ) {
149 if ( node != null && attr_name == null ) {
150 if ( node.childNodes[0] != null ) {
151 // trim and strip html:
152 tag_val = $j.trim( node.firstChild.nodeValue ).replace(/(<([^>]+)>)/ig,"");
155 if ( node != null && attr_name != null ) {
156 if ( typeof attr_name == 'string' ) {
157 tag_val = $j.trim( $j( node ).attr( attr_name ) );
160 for ( var j in attr_name ) {
161 if ( $j( node ).attr( attr_name[j] ).length != 0 )
162 attr_vals[ attr_name[j] ] = $j.trim( $j(node).attr( attr_name[j]) ).replace(/(<([^>]+)>)/ig,"");
164 tag_val = attr_vals ;
167 if ( flag_multiple ) {
168 rObj[ attr ].push( tag_val )
170 rObj[ attr ] = tag_val;
173 // Nothing to return we update the "rObj" directly
177 * Get the html representation of the resource Object parameter
179 getEmbedHTML: function( rObj , options ) {
182 // Set up the output var with the default values:
184 options.width = rObj.width;
185 if(! options.height )
186 options.height = rObj.height
189 if ( options['max_height'] ) {
190 options.height = ( options.max_height > rObj.height ) ? rObj.height : options.max_height;
191 options.width = ( rObj.width / rObj.height ) * options.height;
195 options.style += 'height:' + options.height + 'px;';
198 options.style += 'width:' + options.width + 'px;';
200 if ( rObj.mime.indexOf( 'image' ) != -1 )
201 outHtml = this.getImageEmbedHTML( rObj, options );
203 if ( rObj.mime == 'application/ogg' || rObj.mime == 'video/ogg' || rObj.mime == 'audio/ogg' ) {
204 // Setup the attribute html:
205 var ahtml = ( options['id'] ) ? ' id = "' + options['id'] + '" ': '';
206 ahtml+= 'src="' + rObj.src + '" ' +
207 'style="' + options.style + '" ' +
208 'poster="' + rObj.poster + '" ';
210 if ( rObj.mime == 'application/ogg' || rObj.mime == 'video/ogg' ) {
211 outHtml = '<video ' + ahtml + '></video>';
214 if ( rObj.mime == 'audio/ogg' ) {
215 outHtml = '<audio ' + ahtml + '></audio>';
219 // Return the output. Wrap with a description div if remote_insert_description is on.
221 return ( this.rsd['remote_insert_description'] ) ?
222 this.wrapHtmlDesc(rObj, options, outHtml) :
225 // No output give error:
226 js_log( "ERROR:: no embed code for mime type: " + rObj.mime );
227 return 'Error missing embed code for: ' + escape( rObj.mime );
229 wrapHtmlDesc: function( rObj, options, outHtml ) {
230 var stripedTitle = rObj.title.replace( /File:|Image:|.jpg|.png|.ogg|.ogv|.oga|.svg/ig, '');
232 var titleLink = '<a href="' + rObj.link + '" title="' + stripedTitle + '">' +
233 stripedTitle + '</a>';
234 var cpTitle = gM('rsd-' + this.cp.id + '-title');
235 var remoteProviderLink = '<a href="' + this.cp.homepage + '" '+
236 'title="' + cpTitle + '">' +
238 return '<div class="mw-imported-resource" '+
239 'style="width:' + options.width + 'px;' +
240 'height:' + ( options.height + 20 ) + 'px;">' +
242 gM( 'mwe-import-description', [titleLink, remoteProviderLink]) +
246 * Get the embed html specifically for an image type resource Object.
248 getImageEmbedHTML:function( rObj, options ) {
249 // if crop is null do base output:
250 var imgHtml = '<img ';
251 imgHtml += ( options['id'] ) ? ' id = "' + options['id'] + '" ': '';
252 imgHtml += ' src="' + rObj.edit_url + '" '+
253 'style="' + options.style + '" />';
254 if ( rObj.crop == null )
256 // Else do crop output:
257 return '<div style="width:' + rObj.crop.w + 'px;height: ' + rObj.crop.h + 'px;overflow:hidden;position:relative">' +
258 '<div style="position:relative;top:-' + rObj.crop.y + 'px;left:-' + rObj.crop.x + 'px">' +
264 * Gets an image object from a requested transformation via callback
265 * ( letting api search implementations query the remote server for a
266 * given transformation )
268 * By default just return the existing image.
270 getImageObj:function( rObj, size, callback ) {
276 * Gets the inline wikiText description of the resource Object
278 getInlineDescWiki:function( rObj ) {
279 // return striped html & trim white space
281 return $j.trim( rObj.desc.replace(/(<([^>]+)>)/ig,"") );
282 // No Description available:
286 * Get the licence wikiText tag for a given resource Object.
288 * By default license permission wiki text is cc based template mapping
289 * (does not confirm the templates actually exist)
291 getPermissionWikiTag: function( rObj ) {
293 return '';// no license info
295 // First check if we have a special license template tag already set:
296 if( rObj.license_template_tag )
297 return '{{' + rObj.license_template_tag + '}}';
299 // Check that its a defined creative commons license key:
300 if ( this.rsd.licenses.cc.licenses[ rObj.license.key ] != 'undefined' ) {
301 return '{{Cc-' + rObj.license.key + '}}';
302 } else if ( rObj.license.lurl ) {
303 return '{{Template:External_License|' + rObj.license.lurl + '}}';
308 * Gets the resource import description text
310 getImportResourceDescWiki:function( rObj ) {
311 return gM( 'mwe-imported_from', [rObj.title, this.cp.homepage, gM('rsd-' + this.cp.id + '-title'), rObj.link] );
314 * Get any extra wikitext description for the given resource object.
315 * For content outside of the main template description,
316 * like categories or additional wikitext notes.
318 * By default its an empty string.
320 getExtraResourceDescWiki:function( rObj ) {
325 * Gets a image transformation
326 * by default it just return the poster
328 getImageTransform:function( rObj, opt ) {
333 * Adds additional resource information post clip embedding.
335 addResourceInfoFromEmbedInstance : function( rObj, eb_id ) {
340 * Adds resource info with a callback function
342 * Use full for grabbing extra info that is not available in the initial
343 * search results api request.
345 addResourceInfoCallback:function( rObj, callback ) {
350 * Get the wiki embed code for a given resource object
352 getEmbedWikiCode:function( rObj ) {
353 var layout = ( rObj.layout ) ? rObj.layout:"right"
354 var o = '[[' + this.rsd.fileNS + ':' + rObj.target_resource_title + '|thumb|' + layout;
356 if ( !rObj.target_width && rObj.width ) {
357 rObj.target_width = ( rObj.width < 640 ) ? rObj.width: '640';
360 if ( rObj.target_width )
361 o += '|' + rObj.target_width + 'px';
363 if ( rObj.inlineDesc )
364 o += '|' + rObj.inlineDesc;
370 * Updates / normalizes the target_resource_title
372 updateTargetResourceTitle:function( rObj ) {
373 rObj.target_resource_title = rObj.titleKey.replace( / File: | Image: / , '' );
374 rObj.target_resource_title = this.cp.resource_prefix + rObj.target_resource_title;