removed output-disable in dbms-output fetching procedure
[mediawiki.git] / js2 / mwEmbed / libAddMedia / searchLibs / baseRemoteSearch.js
blob66bc7b4acdafe53cfd50eedcabda9b28a59ebc45
1 /*
2 * Base remote search Object. 
3 * provides the base class for the other search system to extend. 
4 */
5 loadGM( {
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"
8 } )
11 * rsd_default_rss_item_mapping
12
13 *  @key is name of rObj variable
14 *  @value is where to find the value in the item xml
15
16 *  *value format:*
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',
31         'title'         : 'title',
32         'link'          : 'link',
33         'desc'          : 'description',
34         // multiple items
35         'category'  : '.media:category@label|url'
38 var baseRemoteSearch = function( iObj ) {
39         return this.init( iObj );
41 baseRemoteSearch.prototype = {
43         completed_req:0,
44         num_req:0,
45         
46         // ResultsObj holds the array of results
47         resultsObj: { },
49         // Default search result values for paging:
50         offset                   :0,
51         limit                   : 30,
52         more_results    : false,
53         num_results             : 0,
55         /**
56         * Initialise the baseRemoteSearch 
57         * @param {Object} options The set of options for the remote search class
58         */
59         init: function( options ) {
60                 js_log( 'mvBaseRemoteSearch:init' );
61                 for ( var i in options ) {
62                         this[i] = options[i];
63                 }
64                 return this;
65         },
66         getSearchResults:function() {
67                 // Empty out the current results before issuing a request
68                 this.resultsObj = { };
69                 
70                 // Do global getSearchResults bindings
71                 this.last_query = $j( '#rsd_q' ).val();
72                 this.last_offset = this.cp.offset;
73                 
74                 // Set the loading flag:                
75                 this.loading = true;
76         },
77         /*
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)
81         */
82         addRSSData:function( data , provider_url ) {
83                 js_log( 'f:addRSSData' );
84                 var _this = this;
85                 var http_host = '';
86                 var http_path = '';
87                 if ( provider_url ) {
88                         pUrl =  mw.parseUri( provider_url );
89                         http_host = pUrl.protocol + '://' + pUrl.authority;
90                         http_path = pUrl.directory;
91                 }
92                 var items = data.getElementsByTagName( 'item' );
93                 // js_log('found ' + items.length );
94                 $j.each( items, function( inx, item ) {         
95                         var rObj = { };
96                         for ( var attr in rsd_default_rss_item_mapping ) {                              
97                                 _this.mapAttributeToResource( rObj, item, attr );
98                         }
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];
106                                         }
107                                         if ( mw.parseUri( rObj[i] ).host ==  rObj[p] ) {
108                                                 rObj[p] = http_host + http_path + rObj[p];
109                                         }
110                                 }
111                         }
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;
119                         _this.num_results++;
120                 } );
121         },
122         /*
123         * Maps a given attribute to a resource object per mapping defined in 
124         * rsd_default_rss_item_mapping
125         *
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 
129         */
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 );
136                 } else {
137                         var tag_name = selector[0];
138                 }
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( '|' );
145                 }
147                 $j.each( item.getElementsByTagName( tag_name ), function ( inx, node ) {
148                         var tag_val = '';
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,"");
153                                 }
154                         }
155                         if ( node != null && attr_name != null ) {
156                                 if ( typeof attr_name == 'string' ) {
157                                         tag_val = $j.trim( $j( node ).attr( attr_name ) );
158                                 } else {
159                                         var attr_vals = { };
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,"");
163                                         }
164                                         tag_val = attr_vals ;
165                                 }
166                         }
167                         if ( flag_multiple ) {
168                                 rObj[ attr ].push( tag_val )
169                         } else {
170                                 rObj[ attr ] = tag_val;
171                         }
172                 } );
173                 // Nothing to return we update the "rObj" directly
174         }, 
175         
176         /**
177         * Get the html representation of the resource Object parameter
178         */
179         getEmbedHTML: function( rObj , options ) {
180                 if ( !options )
181                         options = { };                  
182                 // Set up the output var with the default values: 
183                 if(! options.width )
184                         options.width = rObj.width;
185                 if(! options.height )
186                         options.height = rObj.height
187                         
188                 var outHtml  = '';
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;
192                 }
193                 options.style = '';
194                 if( options.height )
195                         options.style += 'height:' + options.height + 'px;';
196                         
197                 if( options.width )
198                         options.style += 'width:' + options.width + 'px;';                                                      
199                 
200                 if ( rObj.mime.indexOf( 'image' ) != -1 )
201                         outHtml = this.getImageEmbedHTML( rObj, options );
202                         
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 + '" ';
209                                         
210                         if (  rObj.mime == 'application/ogg' || rObj.mime == 'video/ogg'  ) {
211                                 outHtml = '<video ' + ahtml + '></video>';
212                         }
213                                         
214                         if ( rObj.mime == 'audio/ogg' ) {
215                                 outHtml = '<audio ' + ahtml + '></audio>';
216                         }
217                 }
218                 
219                 // Return the output. Wrap with a description div if remote_insert_description is on.           
220                 if( outHtml != '')
221                         return ( this.rsd['remote_insert_description'] ) ?
222                                         this.wrapHtmlDesc(rObj, options, outHtml) :
223                                         outHtml;
224                         
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 );
228         },
229         wrapHtmlDesc: function( rObj, options, outHtml ) {
230                 var stripedTitle =  rObj.title.replace( /File:|Image:|.jpg|.png|.ogg|.ogv|.oga|.svg/ig, '');
231                 
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 + '">' +
237                                                                         cpTitle + '</a>';                                                                       
238                 return '<div class="mw-imported-resource" '+ 
239                                 'style="width:' + options.width + 'px;' + 
240                                         'height:' + ( options.height + 20 ) + 'px;">' +
241                                         outHtml +
242                                         gM( 'mwe-import-description',  [titleLink, remoteProviderLink]) + 
243                                 '</div>';
244         },
245         /**
246         * Get the embed html specifically for an image type resource Object. 
247         */
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 )
255                         return imgHtml;
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">' +
259                                                 imgHtml +
260                                         '</div>' +
261                                 '</div>';
262         },
263         /**
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 )  
267         * 
268         * By default just return the existing image.
269         */
270         getImageObj:function( rObj, size, callback ) {
271                 callback( { 
272                         'url' : rObj.poster 
273                 } );
274         },
275         /**
276         * Gets the inline wikiText description of the resource Object
277         */
278         getInlineDescWiki:function( rObj ) {
279                 // return striped html  & trim white space
280                 if ( rObj.desc )
281                         return $j.trim( rObj.desc.replace(/(<([^>]+)>)/ig,"") );
282                 // No Description available:  
283                 return '';
284         },
285         /**
286         * Get the licence wikiText tag for a given resource Object.
287         *
288         * By default license permission wiki text is cc based template mapping 
289         * (does not confirm the templates actually exist)
290         */
291         getPermissionWikiTag: function( rObj ) {
292                 if ( !rObj.license )
293                         return '';// no license info
294                         
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 + '}}';
298                         
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 + '}}';
304                 }
306         },
307         /**
308         * Gets the resource import description text
309         */
310         getImportResourceDescWiki:function( rObj ) {
311                 return gM( 'mwe-imported_from', [rObj.title,  this.cp.homepage, gM('rsd-' + this.cp.id + '-title'), rObj.link] );
312         },
313         /**
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. 
317         *
318         * By default its an empty string. 
319         */
320         getExtraResourceDescWiki:function( rObj ) {
321                 return '';
322         },
323         
324         /** 
325         * Gets a image transformation 
326         * by default it just return the poster
327         */
328         getImageTransform:function( rObj, opt ) {
329                 return rObj.poster;
330         },
331         
332         /**
333         * Adds additional resource information post clip embedding. 
334         */
335         addResourceInfoFromEmbedInstance : function( rObj, eb_id ) {
336                 return rObj;
337         },
338         
339         /**
340         * Adds resource info with a callback function
341         *
342         * Use full for grabbing extra info that is not available in the initial 
343         * search results api request.
344         */
345         addResourceInfoCallback:function( rObj, callback ) {
346                 callback();
347         },
348         
349         /**
350         * Get the wiki embed code for a given resource object
351         */
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';
358                 }
360                 if ( rObj.target_width )
361                         o += '|' + rObj.target_width + 'px';
363                 if ( rObj.inlineDesc )
364                         o += '|' + rObj.inlineDesc;
366                 o += ']]';
367                 return o;
368         },
369         /**
370         * Updates / normalizes the target_resource_title
371         */
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;
375         }