1 var mediaWikiSearch = function( iObj ) {
2 return this.init( iObj );
4 mediaWikiSearch.prototype = {
6 //init base class and inherit:
7 var baseSearch = new baseRemoteSearch( iObj );
8 for(var i in baseSearch){
9 if(typeof this[i] =='undefined'){
10 this[i] = baseSearch[i];
12 this['parent_'+i] = baseSearch[i];
15 //inherit the cp settings for
17 //returns a rObj by title
18 addByTitle:function( title , callback){
19 js_log("AddByTitle::" + title);
23 'titles':'File:'+title,
24 'prop':'imageinfo|revisions|categories',
25 'iiprop':'url|mime|size',
26 'iiurlwidth': parseInt( this.rsd.thumb_width ),
33 callback( _this.addSingleResult(data) );
37 clearResults:function(){
41 //update the resultObj with recently uploaded items by current User:
42 getUserRecentUploads:function(wgUser, callback){
47 'list':'recentchanges',
48 'rcnamespace':6, //only files
50 'rclimit':15, //get last 15 uploaded files
57 //loop over the data and group by title
58 if(data.query && data.query.recentchanges){
59 for(var i in data.query.recentchanges){
60 var rc = data.query.recentchanges[i];
61 if( !titleSet[ rc.title ] ){
62 titleSet[ rc.title ]=true;
63 titleStr+= pound + rc.title;
68 //now run the actual query ( too bad we cant use recentchanges as a gennerator
73 'prop':'imageinfo|revisions|categories',
74 'iiprop':'url|mime|size',
75 'iiurlwidth': parseInt( _this.rsd.thumb_width ),
78 'url':_this.cp.api_url
81 _this.addResults(data);
87 getSearchResults:function(){
89 this.parent_getSearchResults();
93 js_log('f:getSearchResults for:' + $j('#rsd_q').val() );
94 //do two queries against the Image / File / MVD namespace:
96 //build the image request object:
100 'gsrsearch': $j('#rsd_q').val(),
101 'gsrnamespace':6, //(only search the "file" namespace (audio, video, images)
103 'gsrlimit': this.cp.limit,
104 'gsroffset': this.cp.offset,
105 'prop':'imageinfo|revisions|categories',
106 'iiprop':'url|mime|size',
107 'iiurlwidth': parseInt( this.rsd.thumb_width ),
110 //set up the number of request:
111 this.completed_req=0;
113 //setup the number of requests result flag:
114 //also do a request for page titles (would be nice if api could query both at the same time)
115 reqObj['gsrwhat']='text';
118 'url':this.cp.api_url
120 js_log('mediaWikiSearch: got data response');
121 //parse the return data
122 _this.addResults( data);
123 //_this.checkRequestDone(); //only need if we do two queries one for title one for text
124 _this.loading = false;
127 //same as below but returns your rObj for convience
128 addSingleResult:function( data ){
129 return this.addResults(data, true);
131 addResults:function( data, returnFirst ){
132 js_log("f:addResults");
135 if( typeof data['query-continue'] != 'undefined'){
136 if( typeof data['query-continue'].search != 'undefined')
137 this.more_results = true;
139 //make sure we have pages to iderate:
140 if(data.query && data.query.pages){
141 for(var page_id in data.query.pages){
142 var page = data.query.pages[ page_id ];
144 //make sure the reop is shared (don't show for now it confusing things)
145 //@@todo support remote repository better
146 if( page.imagerepository == 'shared'){
150 //make sure the page is not a redirect
151 if(page.revisions[0]['*'] && page.revisions[0]['*'].indexOf('#REDIRECT')===0){
152 //skip page is redirect
155 //skip if its an empty or missing imageinfo:
156 if( !page.imageinfo )
160 'titleKey' : page.title,
161 'link' : page.imageinfo[0].descriptionurl,
162 'title' : page.title.replace(/File:|.jpg|.png|.svg|.ogg|.ogv|.oga/ig, ''),
163 'poster' : page.imageinfo[0].thumburl,
164 'thumbwidth' : page.imageinfo[0].thumbwidth,
165 'thumbheight': page.imageinfo[0].thumbheight,
166 'orgwidth' : page.imageinfo[0].width,
167 'orgheight' : page.imageinfo[0].height,
168 'mime' : page.imageinfo[0].mime,
169 'src' : page.imageinfo[0].url,
170 'desc' : page.revisions[0]['*'],
171 //add pointer to parent search obj:
174 'categories':page.categories
177 //attempt to parse out some stuff from the teplate:
178 var desc = rObj.desc.match(/\|Description=(([^\n]*\n)*)\|Source=/)
179 if( desc && desc[1] ){
180 rObj.desc = $j.trim( desc[1] );
182 //likely a audio clip if no poster and type application/ogg
183 //@@todo we should return audio/ogg for the mime type or some other way to specify its "audio"
184 if( ! rObj.poster && rObj.mime == 'application/ogg' ){
185 rObj.mime = 'audio/ogg';
187 //add to the resultObj
188 this.resultsObj[page_id] = rObj;
190 //if returnFirst flag:
192 return this.resultsObj[page_id];
196 //for(var i in this.resultsObj[page_id]){
197 // js_log('added: '+ i +' '+ this.resultsObj[page_id][i]);
201 js_log('no results:' + data);
204 //check request done used for when we have multiple requests to check before formating results.
205 checkRequestDone:function(){
206 //display output if done:
207 this.completed_req++;
208 if(this.completed_req == this.num_req){
212 getImageObj:function( rObj, size, callback ){
213 if( rObj.mime=='application/ogg' )
214 return callback( {'url':rObj.src, 'poster' : rObj.url } );
216 //we can just use direct request urls
217 //@@todo thumb.php has some issues (cant serve the full image size, has poor erro handling etc)
218 /*var baseImgUrl = this.cp.api_url.replace('api.php', 'thumb.php');
219 if ( rObj.mime=='image/jpeg' || rObj.mime=='image/png' ){
220 //if requested size is greater than org size return reduced size obj:
221 if( size.width > rObj.orgwidth){
223 'url' : baseImgUrl + '?f=' + rObj.titleKey.replace(/\s/g, '_') + '&w='+ rObj.orgwidth,
224 'width' : rObj.orgwidth,
225 'height': rObj.orgheight
230 //assuming svg or size is in range: give them requeted size
232 'url' : baseImgUrl + '?f=' + rObj.titleKey + '&w='+ size.width,
233 'width' : size.width,
234 'height': Math.round( ( rObj.orgheight / rObj.orgwidth)*size.width )
239 //his could be depreciated if thumb.php improves
243 'titles':rObj.titleKey,
245 'iiprop':'url|size|mime'
249 reqObj['iiurlwidth']= size.width;
250 js_log('going to do req: ' + this.cp.api_url + ' ' + reqObj );
253 'url' : this.cp.api_url
256 for(var page_id in data.query.pages){
257 var iminfo = data.query.pages[ page_id ].imageinfo[0];
258 //store the orginal width:
259 imObj['org_width']=iminfo.width;
260 //check if thumb size > than image size and is jpeg or png (it will not scale well above its max res)
261 if( ( iminfo.mime=='image/jpeg' || iminfo=='image/png' ) &&
262 iminfo.thumbwidth > iminfo.width ){
263 imObj['url'] = iminfo.url;
264 imObj['width'] = iminfo.width;
265 imObj['height'] = iminfo.height;
267 imObj['url'] = iminfo.thumburl;
268 imObj['width'] = iminfo.thumbwidth;
269 imObj['height'] = iminfo.thumbheight;
272 js_log('getImageObj: get: ' + size.width + ' got url:' + imObj.url);
276 //the insert image function
277 insertImage:function( cEdit ){
279 var cEdit = _this.cEdit;
281 getEmbedHTML: function( rObj , options) {
284 //set up the output var with the default values:
285 var outOpt = { 'width': rObj.width, 'height': rObj.height};
286 if( options['max_height'] ){
287 outOpt.height = (options.max_height > rObj.height) ? rObj.height : options.max_height;
288 outOpt.width = (rObj.width / rObj.height) *outOpt.height;
290 var style_attr = 'style="width:' + outOpt.width + 'px;height:' + outOpt.height +'px"';
291 var id_attr = (options['id'])?' id = "' + options['id'] +'" ': '';
293 //return the html type:
294 if(rObj.mime.indexOf('image')!=-1){
295 //if crop is null do base output:
296 var imgHtml = '<img ' + id_attr + ' src="' + rObj.edit_url + '"' + style_attr + ' >';
297 if( rObj.crop == null)
299 //else do crop output:
300 return '<div style="width:'+rObj.crop.w +'px;height: ' + rObj.crop.h +'px;overflow:hidden;position:relative">' +
301 '<div style="position:relative;top:-' + rObj.crop.y +'px;left:-' + rObj.crop.x +'px">'+
307 if(rObj.mime == 'application/ogg' || rObj.mime == 'audio/ogg'){
309 ' src="' + rObj.src + '" ' +
311 ' poster="'+ rObj.poster + '" '
312 if(rObj.mime.indexOf('application/ogg')!=-1){
313 return '<video ' + ahtml + '></video>';
316 if(rObj.mime.indexOf('audio/ogg')!=-1){
317 return '<audio ' + ahtml + '></audio>';
320 js_log('ERROR:unsupored mime type: ' + rObj.mime);
322 getInlineDescWiki:function( rObj ){
323 var desc = this.parent_getInlineDescWiki( rObj );
324 //just grab the description tag for inline desc:
325 var descMatch = new RegExp(/Description=(\{\{en\|)?([^|]*|)/);
326 var dparts = desc.match(descMatch);
328 if( dparts && dparts.length > 1){
329 desc = (dparts.length == 2) ? dparts[1] : dparts[2].replace('}}','');
330 desc = (desc.substr(0,2) == '1=') ?desc.substr(2): desc;
333 //else return the title since we could not find the desc:
334 js_log('we could not find the Description tag in :' + desc );
337 parseWikiTemplate: function( text ){
338 //@@todo parse wiki Template return object with properties and values
340 //returns the inline wikitext for insertion (template based crops for now)
341 getEmbedWikiCode: function( rObj ){
342 //set default layout to right justified
343 var layout = ( rObj.layout)? rObj.layout:"right"
344 //if crop is null do base output:
345 if( rObj.crop == null)
346 return this.parent_getEmbedWikiCode( rObj );
347 //using the preview crop template: http://en.wikipedia.org/wiki/Template:Preview_Crop
348 //@@todo should be replaced with server side cropping
349 return '{{Preview Crop ' + "\n" +
350 '|Image = ' + rObj.target_resource_title + "\n" +
351 '|bSize = ' + rObj.width + "\n" +
352 '|cWidth = ' + rObj.crop.w + "\n" +
353 '|cHeight = ' + rObj.crop.h + "\n" +
354 '|oTop = ' + rObj.crop.y + "\n" +
355 '|oLeft = ' + rObj.crop.x + "\n" +
356 '|Location =' + layout + "\n" +
357 '|Description =' + rObj.inlineDesc + "\n" +