User:Subh83/JavaScriptTools/utils1.js

Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/****************************************************
* Created by Subhrajit Bhattacharya [[User:Subh83]] *
* Licensed under GNU-GPL v3.0                       *
*****************************************************/
var UserSubh83_utils1 = true;

if (typeof(UserSubh83_utilsMenu)=='undefined') importScript("User:Subh83/JavaScriptTools/utilsMenu.js");
if (typeof(UserSubh83_utilsDOMdynamics)=='undefined') importScript("User:Subh83/JavaScriptTools/utilsDOMdynamics.js");
if (typeof(UserSubh83_utilsCommunications)=='undefined') importScript("User:Subh83/JavaScriptTools/utilsCommunications.js");

// ================================================================
/*** General Utils ***/

// For finding page title

function getPageTitle() {
    if (wgPageName) return wgPageName; 
    MainEditTab = document.getElementById("ca-edit");
    if (MainEditTab) {
        MainEditTabAs = MainEditTab.getElementsByTagName("a");
        if (MainEditTabAs && MainEditTabAs.length>0) {
            titlematch = MainEditTabAs[0].href.match(/title=([^&?=]+)/);
            if (titlematch.length >= 2)
                return titlematch[1];
        }
    }
    var pageTitle = GETparam("title");
    if (pageTitle) return pageTitle;
    var regexS = "wiki\\/([^&#?]*)";
    var regex = new RegExp(regexS);
    var results = regex.exec(window.location.href);
    if( results != null ) return results[1];
    return null;
}

// ================================================================
/*** For finding text in wiki markup and positioning cursor ***/

var WikiMarkupsReplacements = new Array(   // Each pair must have equal length components
    [ "[\\n\\r]" , " " ] , // 1
    [ "{{e\\|" , " 10 " ], // 4
    [ "\\|e=" , "|10" ], // 3
    [ "{{val\\|", "      " ], // 6
    [ "{{math\\|", "       " ], // 7
    [ "{{infobox", "         " ], // 9
    [ "{{([^}|]*?)}}" , "  $1  " ] // n (templates without parameters)
);

var WikiMarkupRegexs = new Array(
    "{{[^|}]*" , // for generic templates try the best - remove template name, leave parameters
    "\\|\\s*[\\w]+?\\s*=" , // parameter names in templates, etc.
    "\\[\\[[^<>[\\]|{}]*?\\|" , // Wiki link with link text
    "<math>.*?<\\/math>" , "<ref[^>]*\\/>" , "<ref[^>]*>.*?<\\/ref>" , // completely remove ref and math tags
    "<\\/?[A-Za-z][A-Za-z0-9]*[^>]*>" , // other HTML-like tags
    "\\[[\\d]*]" , // for removing numbers created by <ref> tags in snippet text
    "\\[[A-Za-z]*:\\/\\/\\S*" , // external links
    "&[A-Za-z0-9]+?;" , // HTML special characters
    "\\\\[A-Za-z]*" , // roman characters e.g. \tau
    "\\s+" , // spaces (for avoiding multiple spaces)
    "[^A-Za-z0-9.;_~%$]"  // other special characters that can have meaning as wiki markups
);

function SplitStringToRemoveMarkups(str) {
    WikiMarkupRegex = new RegExp(WikiMarkupRegexs.join('|'), "gi");

    var ret = { matches: str.match(WikiMarkupRegex) ,
                parts: str.split(WikiMarkupRegex) 
                // , replaced: str.replace(WikiMarkupRegex,'') , regex: WikiMarkupRegex  , str: str 
              };
    return ret;
}

function findPosInText(wikitext, textsnippet) {
    for (i=0; i<WikiMarkupsReplacements.length; i++) {
        ReplacementRegex = new RegExp(WikiMarkupsReplacements[i][0], "gi");
        wikitext = wikitext.replace(ReplacementRegex, WikiMarkupsReplacements[i][1]);
        textsnippet = textsnippet.replace(ReplacementRegex, WikiMarkupsReplacements[i][1]);
    }
    wikiTextSplitted = SplitStringToRemoveMarkups(wikitext);
    strippedWikiText = wikiTextSplitted.parts.join('');
    strippedSnippet = SplitStringToRemoveMarkups(textsnippet).parts.join('');
    /* ShowHTMLinPopup('<pre>'+ 
                       HTMLSpecialCharactersEncode(wikiTextSplitted.str + '\n\n' +
                                                   strippedWikiText + '\n\n' +
                                                   strippedSnippet + '\n\n' +
                                                   wikiTextSplitted.regex)+
                       '</pre>'); */
    
    strippedPos = strippedWikiText.indexOf(strippedSnippet);
    if (strippedPos<0) 
        { alert('Sorry, the attempt to locate the wiki-text failed! Please try with a shorter or different selection.'); return false; }

    cumStrippedPos = 0;
    pp = 0;
    while (pp<wikiTextSplitted.parts.length) {
        if (cumStrippedPos + wikiTextSplitted.parts[pp].length >= strippedPos) break;
        else cumStrippedPos = cumStrippedPos + wikiTextSplitted.parts[pp].length;
        pp++;
    }
    wikiTextPos = 0;
    for (i=0; i<pp; i++) 
        wikiTextPos += (wikiTextSplitted.parts[i].length + wikiTextSplitted.matches[i].length);
    wikiTextPosStart = wikiTextPos + (strippedPos - cumStrippedPos);

    while (pp<wikiTextSplitted.parts.length) {
        if (cumStrippedPos + wikiTextSplitted.parts[pp].length >= strippedPos + strippedSnippet.length) break;
        else cumStrippedPos = cumStrippedPos + wikiTextSplitted.parts[pp].length;
        pp++;
    }
    wikiTextPos = 0;
    for (i=0; i<pp; i++) 
        wikiTextPos += (wikiTextSplitted.parts[i].length + wikiTextSplitted.matches[i].length);
    wikiTextPosEnd = wikiTextPos - (cumStrippedPos - (strippedPos + strippedSnippet.length));

    var retpos = { start: wikiTextPosStart , end: wikiTextPosEnd };
    return retpos;
}

function setSelectionInWikitextFromSnippet(editboxctrl, textsnippet)
{
    pos = findPosInText(editboxctrl.value, textsnippet);
    selectRangeInTextarea(editboxctrl, pos.start, pos.end);
}

// ================================================================
/*** WikiBlame tools ***/

function WikiBlameFromWikitext(pagename, wikitextEncoded) {
    wikiBlameURL = "http://wikipedia.ramselehof.de/wikiblame.php?user_lang=en&lang=en&project=wikipedia" +
                       "&article=" + pagename + "&needle=" + wikitextEncoded + 
                       "&skipversions=0&ignorefirst=0&limit=2000&order=desc&" +
                       "searchmethod=int&force_wikitags=on&binary_search_inverse=false";
    wikiblamewindow = window.open(wikiBlameURL, 'WikiBlame', 
                                     'directories=1,location=1,menubar=1,resizable=1,scrollbars=1,status=1,toolbar=1');
    if (window.focus) wikiblamewindow.focus();
}

var xmlhttpWIKITEXT;
var xmlhttpWIKITEXTSent = false;
var xmlhttpWIKITEXTDone = false;

function WikiBlameFromSnippet(pagename, textsnippetEncoded, secNum, cycles) {
    cycles = (typeof(cycles) != 'undefined') ? cycles : 50;
    if (cycles <= 0) return;

    if (!xmlhttpWIKITEXTSent) {
        fetchURL = (wgServer+wgScript)+"?action=raw&title="+pagename;
        if (secNum >= 0) fetchURL += "&section="+secNum;
        xmlhttpWIKITEXTSent = true;
        xmlhttpWIKITEXT = createXMLHTTP("GET", fetchURL, function(){xmlhttpWIKITEXTDone=true;} );
    }

    if (!xmlhttpWIKITEXTDone || !xmlhttpWIKITEXT || xmlhttpWIKITEXT.readyState!=4)
        setTimeout(WikiBlameFromSnippet, 200, pagename, textsnippetEncoded, secNum, cycles-1);
    else {
        xmlhttpWIKITEXTSent = false;
        xmlhttpWIKITEXTDone = false;

        if (xmlhttpWIKITEXT.status == 200) {
            // Main actions
            pos = findPosInText(xmlhttpWIKITEXT.responseText, decodeURIComponent(textsnippetEncoded));
            if(pos) {
                wikitextEncoded = XEncodeURIComponent(xmlhttpWIKITEXT.responseText.toString().substring(pos.start, pos.end));
                WikiBlameFromWikitext(pagename, wikitextEncoded);
            }
        } else 
            alert("Problem retrieving data - status: " + xmlhttpWIKITEXT.status);
    }

}