Користувач:Oleandr/wikilinker.js

Матеріал з Вікіджерел

Увага: Після публікування слід очистити кеш браузера, щоб побачити зміни.

  • Firefox / Safari: тримайте Shift, коли натискаєте Оновити, або натисніть Ctrl-F5 чи Ctrl-Shift-R (⌘-R на Apple Mac)
  • Google Chrome: натисніть Ctrl-Shift-R (⌘-Shift-R на Apple Mac)
  • Internet Explorer / Edge: тримайте Ctrl, коли натискаєте Оновити, або натисніть Ctrl-F5
  • Opera: натисніть Ctrl-F5
// Український Wiki Linker — шукає вікі посилання для виділеного тексту.
// Поки що використовуєтья RussianStemmer, тож можуть бути незнаачні помилки.
// UkranianStemmer знаходиться в процесі написання.
 
$(function() {
/*
    mw.loader.using( 'ext.wikiEditor', function() {
        if ($('#editform').length) {
            $('#wpTextbox1' ).wikiEditor( 'addToToolbar', {
                'section': 'main',
                'groups': {
                    'oleandr': {
                        'label': 'Oleandr'
                        }
                    }
                });
 
            $('#wpTextbox1').wikiEditor('addToToolbar', {
                'section': 'main',
                'group': 'oleander',
                'tools': {
                    id: {
                        type:'button',
                        action: {type:'callback', execute: poemMain},
                        label:'проза',
                        icon: 'http://upload.wikimedia.org/wikipedia/commons/2/27/Japanese_Map_symbol_%28Library%29.svg'
                    }
                }
            })
        }
    });
*/
 
if (/edit|submit/.test(wgAction))
{
  mwCustomEditButtons['wikilinkerEx'] = [WikiLinkerEx, 'commons/b/bd/Wikilinker.png', 'Український WikiLinker. Шукає вікі-посилання для обраного слова або словосполучення'];
  //importScript('user:Oleandr/JS/stemmer.js','uk');
  //mw.loader.load('//uk.wikipedia.org/wiki/Користувач:Oleandr/JS/stemmer.js');
}
});

function stemPhrase(phrase) {
 
   phrase=phrase.replace(/\s/g, " ");
   phrase=phrase.replace(/—/g, " ");
   phrase=phrase.replace(/»/g, "");
   phrase=phrase.replace(/«/g, "");
   phrase=phrase.replace(/\%/g, "");
   phrase=phrase.replace(/\'/g, "");
   phrase=phrase.replace(/\"/g, "");
   phrase=phrase.replace(/_/g, " ");
   phrase=phrase.replace(/\!/g, " ");
   phrase=phrase.replace(/\?/g, " ");
   phrase=phrase.replace(/\./g, " ");
   phrase=phrase.replace(/\,/g, " ");
   phrase=phrase.replace(/\:/g, " ");
   phrase=phrase.replace(/\s+/g, " ");
   phrase=phrase.substr(0,100);
 
   var rustemmer = new RussianStemmer();
 
   var arr = phrase.split(' ');
   var res = '';
   var next_res = '';
 
   var n = 0;
 
   for (var i in arr) {
      rustemmer.setCurrent(arr[i]);
      rustemmer.stem();
      next_res = rustemmer.getCurrent();
      if (next_res.length > 0) {
        if (next_res != arr[i] && n < 3) {
           res += next_res + '* ';
           n++; // в строке запроса может быть не более 3 звёздочек
        }
        else {
           res += next_res + ' ';
        }
      }
   }
 
   // trim string
   res = res.replace(/(^\s+)|(\s+$)/g, "");
 
   return res;
}
 
function WikiLinkerEx() 
{
	var wpTextbox1 = 0;
	var textScroll = 0;
	var startPos = 0;
	var endPos = 0;
	var txt ="";
	var nItemsSearchLimit = 25;
	var nItemsShowLimit = 7;
	var preparedText='';
 
	wpTextbox1 = document.editform.wpTextbox1;
	// var browserType = 0;
	// var winScroll = document.documentElement.scrollTop;
 
	WLExCancel();
 
    var CantWork = 'Спочатку треба виділити слово або словосплучення.';
    // var range = 0;
 
    wpTextbox1.focus();
 
    textScroll = wpTextbox1.scrollTop;
    startPos = wpTextbox1.selectionStart;
    endPos = wpTextbox1.selectionEnd;
    txt = wpTextbox1.value.substring(startPos, endPos);
 
    // txt = selectedText();
 
    // отсекаем последний пробел
    if (txt.slice(-1) == ' ') 
    {
       txt = txt.slice(0,-1);
       endPos = endPos - 1;
    }
 
    if (txt == '') 
    {
        alert(CantWork);
        return;
    }
 
    processText();
 
    function processText() 
    {
        preparedText = stemPhrase(txt);
 
        requestLength = preparedText.split(' ').length;
 
        var url = wgServer 
        	+ wgScriptPath 
        	+ '/api.php?action=query&list=search&srlimit='
        	+ nItemsSearchLimit 
        	+ '&srprop=&srredirects=1&format=json&srsearch=' 
        	+ preparedText;
 
        /*var jqxhr =*/ $.getJSON(url)
        .done(function(data, textStatus, jqXHR){WLExQuerySuccessProcess(data.query);})
        .error(function(){alert("Your browser does not support XMLHTTP!");return;});
    }
 
    // сравнение по длине строки, без учёта уточнения в скобках
    // чтобы для "Категори*" выдавалось "Категория (значения)", а не "Классификация"
    function compareStringLengths (a, b) 
    {
      a = a.replace(/ \(.*\)/g, "");
      b = b.replace(/ \(.*\)/g, "");
 
      if ( a.length < b.length ) return true;
 
      return false;
    }
 
    function lengthWithoutBrackets(str)
    {
    	str = str.replace(/ \(.*\)/g, "");
    	return str.length; 
    }
 
    function WLExQuerySuccessProcess(query) 
    {	
       if (query.search != undefined)
       { 	   
    	   // dynamic create regular expression, ignore register & first worlds should be == txt  
    	   // matching with original test 
    	   var regExpTxt = new RegExp('^' + txt,"i");
 
    	   var txtRegExPrepared = preparedText.replace(/\*/g, ".*");
 
    	   //matching with prepared test, ignore register
    	   var regExpPreparedText = new RegExp(txtRegExPrepared,"i");
 
    	   // check first world may be relink or abbrivation
 
    	   // first element of array
 
    	   var should_be_first_element = undefined;
 
    	   if (query.search.length > 0)
    	   {
    		   if (!regExpPreparedText.test(query.search[0].title))
    		   {
    			   should_be_first_element = query.search.shift();
    		   }
    	   }
 
    	   // sort  
    	   query.search.sort(function(a,b)
    		 {  
 
    		   var strA = a.title;
    		   var strB = b.title;
 
    		   var hasAText = regExpTxt.test(strA); 
    		   var hasBText = regExpTxt.test(strB);     			      		   
 
    		   if (hasAText && !hasBText) return -1;
    		   if (hasBText && !hasAText) return 1;
 
    		   var retVal = compareStringLengths(strA,strB) ? -1 : 1; 
    		   if (hasAText && hasBText) return retVal;
 
    		   var hasASteamText = regExpPreparedText.test(strA); 
    		   var hasBSteamText = regExpPreparedText.test(strB);
 
    		   // !hasAText && !hasBText
    		   if (hasASteamText && !hasBSteamText) return -1;
    		   if (hasBSteamText && !hasASteamText) return 1;
    		   if (hasASteamText && hasBSteamText) return retVal;
 
    		   // !hasASteamText && !hasBSteamText
    		   return retVal;
    	   });
 
    	   if (should_be_first_element != undefined)
    	   {
    	   		query.search.unshift(should_be_first_element);
    	   }
       }
 
       var checked_index = 0;
 
       /*
       // если в запросе было только одно слово, то выбираем самое короткое название из первых трёх результатов
       // чтобы для "Аглией" выдавалось "Англия", а не "Англиканство"
       if (requestLength == 1) 
       {
          var substr = txt.substr(0,3).toLowerCase();
 
          var min_len = 0;
          if (query.search[0] != undefined)
        	  min_len = lengthWithoutBrackets(query.search[0].title); 
 
          for (var j=0; j<list_item_count; j++) 
          {
        	 var substr_search = query.search[j].title;
 
             if ( substr == substr_search.substr(0,3).toLowerCase() ) 
             {
            	var length = lengthWithoutBrackets(substr_search);
            	if ( length < min_len)
            	{
            		min_len = length;
            		checked_index = j;
            	}
             }
          }
       }
       */
 
       // There are nItemsShowLimit radio buttons items in list 
       var list_item_count = query.search.length;
       if (list_item_count > nItemsShowLimit)
       {
             list_item_count = nItemsShowLimit;
       }
 
       var txtLocal = '<div id="WLExForm">'
       +'<fieldset><legend>'+ preparedText +'</legend>'
       + '<table cellspacing="12">';
 
       var checked_value = "false";
 
 
        for (var k=0; k<list_item_count; k++)
        {
        	var loc_str = query.search[k].title;
 
        	if (k == checked_index)
        		checked_value = 'checked';
        	else
        		checked_value = ''; 
 
        	txtLocal = txtLocal + '<input type="radio" name="preferred_txt" value="' + loc_str + 
        	'" '+ checked_value + '><A href="/wiki/'+ loc_str + '">'
        	+ loc_str +'</A>' 
        	// + '<a href="/wiki/' + loc_str + '" ' + 'title="' + loc_str + '">' + loc_str  + '</a>'
        	+ '</br>';
        } 
 
        // додаємо опцію [[|]] - до списку
        if (list_item_count == 0)
        	checked_value = 'checked';
        else
        	checked_value = '';
 
        txtLocal = txtLocal + '<input type="radio" name="preferred_txt" value="" ' 
                            + checked_value + '><a>[[|]]</a>'; 
 
		txtLocal = txtLocal +  
		'</table></fieldset>' +
		'<input type="button" id="idAddWikiLinkBtn" value="Додати"> '+
		'<input type="button" id="idCancelWikiBtn" value="Відмінити"><br/>'+
		 '</div>';
 
        $('#editform').prepend(txtLocal);
        $('#idAddWikiLinkBtn').click(function(){WLExAdd();});
        $('#idCancelWikiBtn').click(function(){WLExCancel();});
     }
 
    function initialLower(str) 
    {
        return str.substr(0, 1).toLowerCase() + str.substr(1);
     }
 
 
    function WLExCancel() 
    {
    	var form = document.getElementById('WLExForm');
    	if (form != undefined)
    		form.style.display = 'none';
    }
 
    function WLExAdd() 
    {
    	var page_name = $("#WLExForm input:checked")[0].value;
    	var finalTxt = ""; 
 
    	// для "форумы" будет "[[форум]]ы", а не "[[форум|форумы]]"
       if ( initialLower(txt.substr(0, page_name.length)) == initialLower(page_name)  
    		   &&  page_name.length <= txt.length
    		   && page_name.length != 0) 
    	   finalTxt = '[[w:' + txt.substr(0, page_name.length) + ']]' + txt.substr(page_name.length, txt.length - page_name.length);
       else 
    	   finalTxt = '[[w:' + page_name + '|' + txt + ']]';
 
       insertText(finalTxt);
 
       WLExCancel();
    }
 
    function insertText(finalTxt)
    {
    	wpTextbox1.selectionStart = startPos;
    	wpTextbox1.selectionEnd = endPos;
        wpTextbox1.value = wpTextbox1.value.substring(0, startPos) + finalTxt + wpTextbox1.value.substring(endPos);
        wpTextbox1.selectionEnd = startPos + finalTxt.length;
        wpTextbox1.scrollTop = textScroll;
    }
}