MediaWiki:Gadget-TemplatePreloader.js

From Wikisource
Jump to navigation Jump to search
Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Clear the cache in Tools → Preferences

For details and instructions about other browsers, see Wikipedia:Bypass your cache.

/* Preload Template:Header when adding a new text */
/* For help, see '''Help:Header preloading script gadget''' */
/*jshint asi:true, eqnull:true, laxbreak:true, forin: false */
/*global mw, $, sajax_init_object */
function preloadHeaderTemplate()
{
    var wpTextbox1 = document.getElementById("wpTextbox1")
    if (wpTextbox1.value == "")
    {
        //fill in header template
        var subpageDepth = 0
        var isSubpage
        var pathToTOC = "" //typically "../"
        var subpageTitle
        var subpageTitleRegExp
        var rawBasePageRequest
        var tocPageTitle
        var beginningOfShortSectionTitle //for example, if tocPageTitle == "Democracy in America/Volume 2", then beginningOfShortSectionTitle == "Volume 2, " - this is used to determine the values for "previous" and "next"
        var rawTocPageRequest //table of contents page
        var rawTocPageWithoutHeader
        
        //title
        var wpTextbox1value = "{" + "{header\n | title      = "
        if (mw.config.get('wgTitle').indexOf("/") != -1) //a slash could indicate that it's a subpage
        {
            rawBasePageRequest = new XMLHttpRequest()
            
            //determine where the base page name ends and where the subpage name begins
            for (var slashPosition = mw.config.get('wgTitle').indexOf("/"); slashPosition != -1; slashPosition = mw.config.get('wgTitle').indexOf("/", slashPosition + 1))
            {
                rawBasePageRequest.open("GET", mw.config.get('wgServer') + mw.config.get('wgScript') + "?title=" + mw.config.get('wgTitle').substr(0, slashPosition) + "&action=raw", false)
                rawBasePageRequest.send(null)
                
                if (rawBasePageRequest.responseText != "") //base page found
                {
                    wpTextbox1value += "[["
                    
                    //output however many "../" will take us to the base page
                    for (var i = mw.config.get('wgTitle').lastIndexOf("/"); i >= slashPosition; i = mw.config.get('wgTitle').lastIndexOf("/", i - 1))
                    {
                        wpTextbox1value += "../"
                        subpageDepth += 1
                    }
                    
                    wpTextbox1value += "]]"
                    
                    isSubpage = true
                    break
                }
            }
            
            //output
            if (isSubpage == false) //despite the slash in this page's title, no base page was found, so assume that this page is the base page (for example, "9/11 Commission Report")
            {
                wpTextbox1value += mw.config.get('wgTitle')
            }
            
            //round 2: find the table of contents page, not necessarily the same as the base page
            var slashPosition = mw.config.get('wgTitle').lastIndexOf("/")
            if (subpageDepth > 1)
            {
                rawTocPageRequest = new XMLHttpRequest()
                
                for (; slashPosition != -1; slashPosition = mw.config.get('wgTitle').lastIndexOf("/", slashPosition - 1))
                {
                    pathToTOC += "../"
                    
                    tocPageTitle = mw.config.get('wgTitle').substr(0, slashPosition) //will be used later
                    rawTocPageRequest.open("GET", mw.config.get('wgServer') + mw.config.get('wgScript') + "?title=" + tocPageTitle + "&action=raw", false)
                    rawTocPageRequest.send(null)
                    
                    if (rawTocPageRequest.responseText != "") //TOC page found
                    {
                        break
                    }
                }
            }
            else //if the depth is only 1 then the base page and the TOC page are the same
            {
                //set up variables without going through the whole loop
                pathToTOC = "../"
                tocPageTitle = mw.config.get('wgTitle').substr(0, slashPosition)
                rawTocPageRequest = rawBasePageRequest
            }
            //for later
            subpageTitle = mw.config.get('wgTitle').substr(slashPosition + 1) //subpageTitle is relative to the table of contents, not the base page
            var indexOfSlashInTocPageTitle = tocPageTitle.indexOf("/")
            if (indexOfSlashInTocPageTitle != -1)
            {
                beginningOfShortSectionTitle = tocPageTitle.substring(tocPageTitle.indexOf("/") + 1).replace(/\//g, ", ") + ", " //change / to , - better than doing nothing
            }
            else
            {
                beginningOfShortSectionTitle = ""
            }
        }
        else //definitely not a subpage
        {
            wpTextbox1value += mw.config.get('wgTitle')
        }
        
        //author
        wpTextbox1value += "\n | author     = "
        if (isSubpage)
        {
            try
            {
                wpTextbox1value += /\{\{[\s]*[Hh]eader[2]?[\s]*[\s\S]*\|[\s]*author[\s]*\=([^\||\}\}]*)/.exec(rawTocPageRequest.responseText)[1].replace(/^\s+/,"").replace(/\s+$/,"")
            }
            catch (e)
            {
                //if there was an error, just leave the field blank
            }
        }
        
        //translator
        wpTextbox1value += "\n | translator = "
        if (isSubpage)
        {
            try
            {
                wpTextbox1value += /\{\{[\s]*[Hh]eader[2]?[\s]*[\s\S]*\|[\s]*translator[\s]*\=([^\||\}\}]*)/.exec(rawTocPageRequest.responseText)[1].replace(/^\s+/,"").replace(/\s+$/,"")
            }
            catch (e)
            {
                //if there was an error, just leave the field blank
            }
        }
        
        //section
        wpTextbox1value += "\n | section    = "
        if (isSubpage) //only subpages have section titles
        {
            try
            {
                subpageTitleRegExp = subpageTitle.replace(/[ _]/, "[ _]")  //subpageTitleRegExp will also be used later
                subpageTitleRegExp = "[" + subpageTitleRegExp[0].toUpperCase() + subpageTitleRegExp[0].toLowerCase() + "]" + subpageTitleRegExp.substr(1) //MediaWiki is not case-sensitive on the first letter
                
                wpTextbox1value += (new RegExp("\\[\\[/" + subpageTitleRegExp + "\\|(.*)\]\]")).exec(rawTocPageRequest.responseText)[1]
            }
            catch (e)
            {
                //if there was an error, fall back on just adding the section name
                wpTextbox1value += subpageTitle.replace(/\//g, ", ")
            }
        }
        
        //used for both previous page and next page determination
        var indexOfCurrentPageInTableOfContents = -1 //the -1 makes sure that if the value can't be found, "undefined" isn't used instead
        
        //previous
        wpTextbox1value += "\n | previous   = "
        try
        {
            rawTocPageWithoutHeader = rawTocPageRequest.responseText.substring(/(\{\{[Hh]eader[2]?[^\}\}]*)/.exec(rawTocPageRequest.responseText)[1].length) //cut off the header before searching
            
            indexOfCurrentPageInTableOfContents = rawTocPageWithoutHeader.indexOf((new RegExp("\\[\\[/" + subpageTitleRegExp + "[\\||\\]\\]]")).exec(rawTocPageWithoutHeader)[0])
            
            var indexOfTargetLink = rawTocPageWithoutHeader.lastIndexOf("[[/", indexOfCurrentPageInTableOfContents - 3)
            var previousPageTitle = /\[\[\/([^\||\]\]]*)/.exec(rawTocPageWithoutHeader.substring(indexOfTargetLink, indexOfCurrentPageInTableOfContents))[1]
            
            wpTextbox1value += "[[" + pathToTOC + previousPageTitle + "|" + beginningOfShortSectionTitle + previousPageTitle.replace(/\//g, ", ") + "]]" //change / to , - better than doing nothing
        }
        catch (e)
        {
            //if there was an error, just leave the field blank
        }
        
        //next
        wpTextbox1value += "\n | next       = "
        try
        {
            if (indexOfCurrentPageInTableOfContents != -1) //if we don't know where we are in the list, do not wrap back to the beginning - strangely, an exception doesn't get thrown if I leave indexOfCurrentPageInTableOfContents alone, and the "next" algorithm jumped back to the beginning of the table of contents page
            {
                var indexOfTargetLink = rawTocPageWithoutHeader.indexOf("[[/", indexOfCurrentPageInTableOfContents + subpageTitle.length + 2)
                if (indexOfTargetLink != -1) //if we're at the end of the list, do not wrap back to the beginning
                {
                    var nextPageTitle = /\[\[\/([^\||\]\]]*)/.exec(rawTocPageWithoutHeader.substring(indexOfTargetLink))[1]
                    wpTextbox1value += "[[" + pathToTOC + nextPageTitle + "|" + beginningOfShortSectionTitle + nextPageTitle.replace(/\//g, ", ") + "]]" //change / to , - better than doing nothing
                }
            }
        }
        catch (e)
        {
            //if there was an error, just leave the field blank
        }

        // year (except on subpages)
        if( mw.config.get('wgTitle').indexOf("/") == -1 )
        {
            wpTextbox1value += "\n | year       = ";
        }
        
        //notes
        wpTextbox1.value = wpTextbox1value + "\n | notes      = \n}}\n\n"
    }
}

/* Preload Template:Textinfo when starting a discussion page */
function preloadTextinfoTemplate()
{
    var wpTextbox1 = document.getElementById("wpTextbox1")
    if (wpTextbox1.value == "" && !document.URL.match('&section=new') )
    {
        wpTextbox1.value = "{" + "{textinfo\n | edition      = \n | source       = \n | contributors = \n | progress     = \n | notes        = \n | proofreaders = \n}}\n"
    }
}


// Try to fill field when creating an author page. Fields always filled, are
// lastname, firstname, lastinitial, wikipedia. Birth/Death year filled iff an
// article is available on wp:en. Try also to avoid duplicate author:
// by creating a redirect if the wikipedia is non empty, its title
// is different from the current Author:title and an Author:new_title
// exists.
window.author_v2 = {

check_redirect : function (title, text_box)
{
    var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath')
        + "/api.php?format=xml&action=query&prop=info&titles="
        + encodeURIComponent(title);
    // FIXME: Use of "sajax_init_object" is deprecated. Sajax is deprecated, use jQuery.ajax or mediawiki.api instead.
    var request = sajax_init_object();
    request.open('GET', url, true);
    request.onreadystatechange = function () {
        if (request.readyState == 4) {
            var xml = request.responseXML;
            if (xml == null) return ;
            var page = xml.getElementsByTagName( "page" )[0];
            if (page.getAttribute("missing") != "")
               text_box.value = '#REDIRECT [[' + title + ']]';
        }
    };
    request.send(null);
},

author_fill_callback : function (data)
{
    try {
        var wpTextbox1 = document.getElementById("wpTextbox1");
        if (wpTextbox1 && !data.query.pages["-1"]) {
            for (var ids in data.query.pages) {
                wpTextbox1.value = wpTextbox1.value.replace(/( *\\| *wikipedia *= *)/, "$1" + data.query.pages[ids].title);
                var cats = data.query.pages[ids].categories;
                for (var i = 0; i < cats.length; ++i) {
                    var m = cats[i].title.match(/Category:(\d+) deaths/);
                    if (m)
                        wpTextbox1.value = wpTextbox1.value.replace(/( *\\| *deathyear *= *)/, "$1" + m[1]);
                    m = cats[i].title.match(/Category:(\d+) births/);
                    if (m)
                        wpTextbox1.value = wpTextbox1.value.replace(/( *\\| *birthyear *= *)/, "$1" + m[1]);
                }
                break;
            }
            // This can undo all the above works by preferring to create a redirect to an existing author:
            window.author_v2.check_redirect('Author:' + data.query.pages[ids].title, wpTextbox1);
       }
    }
    catch (err) { }
},

create_script_obj : function (url)
{
    var scriptObj = document.createElement("script");
    scriptObj.setAttribute("type", "text/javascript");
    scriptObj.setAttribute("src", url);
    document.body.appendChild(scriptObj);
},

split_title : function ()
{
    return mw.config.get('wgTitle').replace(/ \(.*\)/, "").split(" ");
},

get_special_word_pos : function (words)
{
    var i;
    for (i = 0; i < words.length; ++i) {
        if (words[i] == 'van' || words[i] == 'von' ||
            words[i] == 'le' || words[i] == 'de') {
           return i;
        }
    }
    return -1;
},

get_first_name : function (words)
{
    return words.slice(0, window.author_v2.get_special_word_pos(words)).join(" ");
},

get_last_name : function(words)
{
    return words.slice(window.author_v2.get_special_word_pos(words)).join(" ");
},

get_last_initial : function(words)
{
    // get_last_name() can't be used here, we want the last word or the next
    // word following a special word
    var lastname = words[words.length - 1];
    var pos = window.author_v2.get_special_word_pos(words);
    if (pos != -1 && pos < words.length - 1)
         lastname = words[pos + 1];

    var last_initial = lastname.slice(0, 2);
    // O'Donnel --> Od
    if (lastname.length > 2 && last_initial.charAt(1) == "'")
        last_initial = last_initial.charAt(0) + lastname.charAt(2).toLowerCase();
    return last_initial;
},

/* Preload Template:Author when starting an author page, derived from [[User:Remember the dot]] code */
preloadAuthorTemplate : function()
{
    var wpTextbox1 = document.getElementById("wpTextbox1")
    if (wpTextbox1.value != "")  return;

    // try to figure out what value we can fill, broken in some case because
    // it's difficult to handle name like Tom Van Moore but Tom van Moore is
    // handled correctly.
    var words = window.author_v2.split_title();
    var lastname = window.author_v2.get_last_name(words);
    var firstname = window.author_v2.get_first_name(words);
    var last_initial = window.author_v2.get_last_initial(words);

    wpTextbox1.value  = "{" + "{author\n" +
                        " | firstname    = " + firstname + "\n" +
                        " | lastname     = " + lastname + "\n" +
                        " | last_initial = " + last_initial + "\n" +
                        " | birthyear    = <" + "!--data now imported from wikidata, please consider deleting once matched-->\n" +
                        " | deathyear    = <" + "!--data now imported from wikidata, please consider deleting once matched-->\n" +
                        " | description  = \n" +
//no longer need to specifically capture here, data to Wikidata
//                        " | image        = \n" +
//                        " | wikipedia    = \n" +
//                        " | wikiquote    = \n" +
//                        " | commons      = \n" +
//                        " | commonscat   = \n" +
//                        " | wikidata     = \n" +
                        "}}\n\n" +
                        "==Works==\n\n";

    var base_url = "//en.wikipedia.org" + mw.config.get('wgScriptPath');

    var url = base_url + "/api.php?format=json&redirects"
        + "&callback=window.author_v2.author_fill_callback&action=query&prop=categories&cllimit=20&titles="
        + encodeURIComponent(mw.config.get('wgTitle'));

    window.author_v2.create_script_obj(url);
}

}


// Preload Template:Process header when starting a project or help page
// Simple preloader based on the preload code for Template:Textinfo
function preloadProcessHeaderTemplate()
{
    var wpTextbox1 = document.getElementById("wpTextbox1")
    if (wpTextbox1.value == "" && !document.URL.match('&section=new') )
    {
        wpTextbox1.value = "{" + "{process header\n | title    = \n | section  = \n | previous = \n | next     = \n | shortcut = \n | notes    = \n}}\n"
    }
}




// Preload Template:Portal header when starting a portal page
// Simple preloader based on the preload code for Template:Textinfo
function preloadPortalHeaderTemplate()
{
    var wpTextbox1 = document.getElementById("wpTextbox1")
    if (wpTextbox1.value == "" && !document.URL.match('&section=new') )
    {
        wpTextbox1.value = "{" + "{portal header\n | title     = \n | class     = \n | subclass1 = \n | reviewed  = \n | shortcut  = \n | notes     = \n}}\n\n==Works==\n\n"
    }
}

// Preload Template:Portal review when starting a portal discussion page
// Simple preloader based on the preload code for Template:Textinfo
function preloadPortalReviewTemplate()
{
    var wpTextbox1 = document.getElementById("wpTextbox1")
    if (wpTextbox1.value == "" && !document.URL.match('&section=new') )
    {
        wpTextbox1.value = "{" + "{portal review\n | class      = \n | subclass1  = \n | subclass2  = \n | classifier = \n | reviewer   = \n | notes      = \n}}\n"
    }
}




// Preload Template:Translation header when starting a translation page
// Simple preloader based on the preload code for Template:Textinfo
function preloadTranslationHeaderTemplate()
{
    var wpTextbox1 = document.getElementById("wpTextbox1")
    if (wpTextbox1.value == "" && !document.URL.match('&section=new') )
    {
        wpTextbox1.value = "{" + "{translation header\n | title    = \n | author   = \n | section  = \n | previous = \n | next     = \n | year     = \n | language = \n | original = \n | notes    = \n}}\n"
    }
}




// Main preloader loading code:
switch (mw.config.get('wgNamespaceNumber')) {
    case 0: //main
        $(preloadHeaderTemplate)
        break
    case 1: //Talk
        $(preloadTextinfoTemplate)
        break
    case 4: //Wikisource
        $(preloadProcessHeaderTemplate)
        break
    case 12: //Help
        $(preloadProcessHeaderTemplate)
        break
    case 100: //Portal
        $(preloadPortalHeaderTemplate)
        break
    case 101: //Portal talk
        $(preloadPortalReviewTemplate)
        break
    case 102: //Author
        $(window.author_v2.preloadAuthorTemplate)
        break
    case 114: //Translation
        $(preloadTranslationHeaderTemplate)
}