میڈیاویکی:Gadget-advanced-search.js

تفصیل کے لیے کھولیں کے بٹن پر کلک کریں یاددہانی: محفوظ کرنے کے بعد تازہ ترین تبدیلیوں کو دیکھنے کے لیے آپ کو اپنے براؤزر کا کیش صاف کرنا ہوگا۔

  • فائرفاکس/ سفاری: جب Reload پر کلک کریں تو Shift دبا کر رکھیں، یا Ctrl-F5 یا Ctrl-R دبائیں (Mac پر R- )
  • گوگل کروم: Ctrl-Shift-R دبائیں (Mac پر Shift-R-⌘)
  • انٹرنیٹ ایکسپلورر: جب Refresh پر کلک کریں تو Ctrl یا Ctrl-F5 دبائیں
  • اوپیرا: Tools → Preferences میں جائیں اور کیش صاف کریں

/**
 * Improve advanced search by adding 
 * options suitable for commons
 *
 * Maintainer: [[User:Bawolff]]
 * Created in 2014
 */
mw.loader.using( ['mw.Api', 'jquery.suggestions'], function () {
 if ( mw.config.get( 'wgCanonicalSpecialPageName' ) !== 'Search' ) {
  return;
 }

 var i18n = {
  en: {
   'header-cat': 'Search by category:',
   'header-file': 'File options:',
   'cat-any': 'In any of these categories:',
   'cat-all': 'In all of these categories:',
   'cat-none': 'In none of these categories:',
   'cat-depth': 'Include subcategories up to a depth of:',
   'file-type': 'Only include the following types of files:',
   'file-license': 'Copyright status:',
   'file-type-all': 'All',
   'file-type-multimedia': 'Multimedia',
   'file-type-jpeg': 'Photographs (JPEG)',
   'file-type-vector': 'Vector images (SVG)',
   'file-type-drawing': 'Drawing',
   'file-pd': 'Do absolutely anything with it (Public domain)',
   'file-cc': 'Freely re-usable under a Creative Commons license',
   'file-any': 'Show all (All files on commons can be re-used under certain conditions)',
  }
 };
 var lookup = function( key ) {
  var lang = mw.config.get( 'wgUserLanguage' );
  if ( i18n[ lang ] && i18n[ lang ][ key ] ) {
   return i18n[ lang ][ key ];
  }
  return i18n.en[ key ];
 };

 var expand = function( str ) {
  return str.replace( /\$([a-z-]+)/g, function( match, p1 ) {
   return lookup( p1 );
  } );
 };

 var renderSearchSuggest = function( suggestion ) {
  var split = splitField( suggestion ),
   lastBit;
  if ( split.length >= 2 ) {
   lastBit = split[split.length - 2];
  } else {
   mw.log( "No commas in search suggestion?" );
   lastBit = suggestion;
  }
  $( this ).text( lastBit );
 };
 var fetchSearchQuery = function( input, callback ) {
//http://commons.wikimedia.org/w/api.php?action=query&generator=allpages&gapnamespace=14&gaplimit=7&gapprefix=Cat&prop=categoryinfo|links|templates&tllimit=max&pllimit=max&tltemplates=Template:Category%20redirect&plnamespace=14
  var lastInput = splitField( input );
  lastInput = lastInput ? lastInput[lastInput.length - 1] : '';
  if ( lastInput.match( /^\s*$/ ) ) {
   callback( [] );
   return;
  }
  var api = new mw.Api();
  api.get( {
   action: 'query',
   generator: 'allpages',
   gapnamespace: 14,
   gaplimit: 5,
   gapprefix: lastInput,
   prop: "categoryinfo|links|templates",
   tllimit: "max",
   pllimit: "max",
   tltemplates: "Template:Category_redirect",
   plnamespace: 14,
   format: 'json'
  }).done( function( data1 ) {
   // This would be much more efficient if we did at same time.
   api.get( {
    action: 'query',
    generator: 'search',
    gsrnamespace: 14,
    gsrlimit: 5,
    gsrsearch: lastInput,
    prop: "categoryinfo|links|templates",
    tllimit: "max",
    pllimit: "max",
    tltemplates: "Template:Category_redirect",
    plnamespace: 14,
    format: 'json'
   }).done( function( data2 ) {
    var suggestions = [];
    var formatSuggestion = function( item ) {
     // Kill the namespace, add the comma separator as a hint to user.
     // Needs to be full search text. renderSearchSuggest will cause only part to be displayed.
     if ( input.match( /,\s/ ) ) {
      return input.replace( /,\s[^,]*$/, '' ) + ', ' + item.replace( /^[^:]*:/, '' ) + ', ';
     } else {
      return item.replace( /^[^:]*:/, '' ) + ', ';
     }
    };
    if ( !(data1 && data1.query && data1.query.pages && data2 && data2.query && data2.query.pages ) ) {
     mw.log( "error fetching data" );
     return;
    }
    var combinedResults = $.extend( {}, data1.query.pages, data2.query.pages );
    for( var i in combinedResults ) {
     // XXX does not do de-duplication in regards to cat redirects.
     if ( combinedResults[i].templates !== undefined ) {
      for( var j in combinedResults[i].links ) {
       suggestions[suggestions.length] = formatSuggestion( combinedResults[i].links[j].title );
       if ( j > 5 ) break;
      }
     } else if ( combinedResults[i].categoryinfo.size > 5 ) {
      // Realistically, most people won't want super small categories.
      suggestions[suggestions.length] = formatSuggestion( combinedResults[i].title );
     }
    }
    callback( suggestions );
   });
  });
 };

 var add = function () {
  if ( !$( '#mw-searchoptions' ).length ) {
   return;
  }
  // This doesn't convert numbers...
  var html = '<div class="sr-category"><h4>$header-cat </h4><div class="divider"/><table border="0"><tbody><!--<tr><td><label for="search-cat-any">$cat-any </label></td><td><input id="search-cat-any"></input></td></tr>--><tr><td><label for="search-cat-all">$cat-all </label></td><td><input id="search-cat-all" name="search-cat-all" size="50"></input></td></tr><tr><td><label for="search-cat-none">$cat-none </label></td><td><input id="search-cat-none" name="search-cat-none" size="50"></input></td></tr><!--<tr><td><label for="search-cat-depth">$cat-depth </label></td><td><select id="search-cat-depth" name="search-cat-depth"><option value="1">1</option><option value="2" selected>2</option><option value="3">3</option></select></td></tr>--></tbody></table></div><div class="sr-file" style="clear:both"><h4>$header-file </h4><div class="divider"><table border="0"><tr><td>$file-license </td><td><select id="search-file-copyright" name="search-file-copyright"><option value="any">$file-any </option><option value="pd">$file-pd</option><option value="by">$file-cc</option></select></td></tr><tr><td>$file-type</td><td><select id="search-file-type" name="search-file-type"><option value="">$file-type-all</option><!--<option value="ogv oga ogg webm mid midi flac wav gif">$file-type-multimedia</option>--><option value="webm">WebM</option><option value="pdf">PDF</option><option value="png">PNG</option><option value="gif">GIF</option><option value="jpg">$file-type-jpeg</option><option value="svg">$file-type-vector</option></select></td></tr></table><input type="hidden" name="search-orig-query" value="" id="search-orig-query"/></div><br style="clear:both">';
  
  $( '#mw-searchoptions' ).prepend( $( expand( html ) ) );

  restoreDefaults( [
   "search-cat-all", "search-cat-none", "search-cat-depth", "search-file-copyright", "search-file-type"
  ] );
  if ( mw.util.getParamValue( 'search-orig-query' ) !== null ) {
   $( '#powerSearchText' ).val( mw.util.getParamValue( 'search-orig-query' ) );
  }

  $( '#powersearch' ).submit( fixForm );

  $('#search-cat-all, #search-cat-none' ).suggestions( {fetch: fetchSearchQuery, cache: true, result: {render: renderSearchSuggest } } );

 };

 var fixForm = function () {
  var $searchBox = $( '#powerSearchText' );
  var addedText = ' ';
  var trimField = function( input ) {
   if ( input === null || input === undefined ) {
    input = '';
   }
   input = input + ''; // FIXME why was I casting to string in first place?
   input = input.replace( /^\s*/, '' ).replace( /\s*$/, '' );
   return input;
  };
  var anyCat = splitField( $( '#search-cat-all' )[0].value );
  $.each( anyCat, function() {
   var field = trimField( this );
   if ( field === '' ) return;
   addedText += ' incategory:"' + field + '"';
  } );

  var noCat = splitField( $( '#search-cat-none' )[0].value );
  $.each( noCat, function() {
   var field = trimField( this );
   if ( field === '' ) return;
   addedText += ' -incategory:"' + field + '"';
  } );

  var fileTypes = $( '#search-file-type' ).val().split( ' ' );
  $.each( fileTypes, function() {
   var field = trimField( this );
   if ( field === '' ) return;
   addedText += ' intitle:' + field;
  } );

  var copyright = $( '#search-file-copyright' ).val();
  if ( copyright === 'pd' ) addedText += ' hastemplate:PD-Layout';
  if ( copyright === 'cc' ) addedText += ' hastemplate:CC-Layout';

  $( '#search-orig-query' ).val( $searchBox.val() );
  $searchBox[0].value += addedText;
 };

 

 var splitField = function( text ) {
  var res = text.split( /,\s+/ );
  if ( res.length === 1 && res[0].match( /^\s*$/ ) !== null ) {
   return [];
  }
  return res;
 };

 // Security note: The elements of list should not come from user input.
 var restoreDefaults = function( list ) {
  $.each( list, function() {
   var val = mw.util.getParamValue( this );
   if ( val === null || val === '' ) return;
   $( '#' + this ).val( val );
  } );
 };

 add();

} );