Jump to content

User:Cleared as filed/afd vote.js

From Wikipedia, the free encyclopedia
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.
// [[User:Cleared as filed/afd_vote.js]] - AFD auto-voting and shortcuts

// requires: wikipage.js, wikipageAfd.js, wikiedit.js, util.js, shortcuts.js, datestamp.js
// enhanced by: advanced_sig.js

// originally based on http://en.wikipedia.org/wiki/User:Quarl/afd_vote.js

//  - asynchronous updating (never opens new windows)
//  - live updating of log page
//  - huge list of shortcut expansions and other shortcut features
//  - more "vote" buttons such as in original article
//  - escaping bugs ('&&', '+', etc) fixed
//  - refuse to create AFD pages (in case of more escaping bugs)

//<pre><nowiki>

if(typeof window.makeSignature=='undefined')makeSignature=function(){return "~~~~"};

var afd_vote_summary_prompt = true;

var afd_vote_shortcuts = Shortcuts({
            'D'         : 'Delete',
            'DA'        : 'Delete all',
            'K'         : 'Keep',
            'M'         : 'Merge',
            'MV'        : 'Move',
            'R,RD'      : 'Redirect',
            'RW'        : 'Rewrite',
            'T'         : 'Transwiki',
            'WD'        : 'Weak delete',
            'SD'        : 'Strong delete',
            'SP'        : 'Speedy delete',
            'SK'        : 'Strong keep',
            'SM'        : 'Slight merge',
            'WK'        : 'Weak keep',
            //'SPK'     : '[[Wikipedia:Speedy keep|Speedy keep]]',
            'SPK'       : 'Speedy keep',
            'C'         : 'Comment',
            'MC'        : 'Metacomment',
            'BJAODN,BJ' : 'BJAODN'
            });

var afd_comment_shortcuts = Shortcuts( {
            'PN'                          : 'per nomination',
            'NN'                          : '[[WP:N|non-notable]]',
            'V,VAIN,VANITY'               : '[[WP:VAIN|vanity]]',
            'NNBIO'                       : '[[WP:BIO|non-notable biography]]',
            'NNVBIO'                      : '[[WP:BIO|non-notable vanity biography]]',
            'NNWEB'                       : '[[WP:WEB|non-notable website]]',
            'NNWEBCOMIC '                 : '[[WP:WEB|non-notable webcomic]]',
            'NNBLOG,NNWEBLOG'             : '[[WP:WEB|non-notable weblog]] ',
            'NNFORUM,NNWEBFORUM'          : '[[WP:WEB|non-notable web forum]] ',
            'NNSOFTWARE,NNSOFT,NNSW'      : '[[WP:SOFTWARE|non-notable software]] ',
            'NNCORP,NNCOMPANY'            : '[[WP:CORP|non-notable corporation]]',
            'NNMUSIC'                     : '[[WP:MUSIC|non-notable musical group]]',
            'NNBAND'                      : '[[WP:MUSIC|non-notable band]]',
            'NNUNEO'                      : '[[Wikipedia:Avoid_neologisms|non-notable unstable neologism, i.e. protologism]]',
            'NNUUNEO'                     : '[[Wikipedia:Avoid_neologisms|non-notable unverifiable unstable neologism, i.e. protologism]]',
            'NNFICT,NNFICTION'            : '[[WP:FICT|non-notable reference to fictional work]]',
            'NNFICTC,NNFICTCHAR,NNCHAR'   : '[[WP:FICT|non-notable character from fictional work]] ',
            'FANCRUFT,NNFAN'              : '[[Wikipedia:Fancruft|fancruft]]',
            'NNFANFIC'                    : '[[Wikipedia:Fancruft|non-notable fan fiction]]',
            'NNGAME'                      : '[[WP:N|non-notable]] online gaming group',
            'U'                           : '[[WP:V|unverifiable]]',
            'UPH'                         : '[[WP:V|unverifiable]], possible [[WP:HOAX|hoax]]',
            'OR'                          : '[[WP:NOR|original research]]',
            'UOR'                         : '[[WP:V|unverifiable]] and/or [[WP:NOR|original research]]',
            'H'                           : '[[WP:HOAX|hoax]]',
            'HSANC,HSANCT,HSANCTION'      : '[[WP:HOAX|hoax]], and sanction article author',
            'ATTACK'                      : '[[WP:CSD|attack page]]',
            'WISHSP,WISHEXPAND'           : 'I wish for expansion of [[WP:CSD]] so that this kind of article could be speedy-deleted when no notability is asserted ',
            'UNENC,UNENCYCLO,NOTPEDIC'    : '[[WP:NOT|unencyclopedic]]',
            'NOT'                         : '[[WP:NOT|Wikipedia is not]]',
            'NOTADVERT'                   : '[[WP:NOT|Wikipedia is not a vehicle for advertising]] ',
            'NOTBALL,NOTCRYSTAL'          : '[[WP:NOT|Wikipedia is not a crystal ball]] ',
            'NOTCRUFT'                    : '[[WP:NOT|Wikipedia is not an indiscriminate collection of information]] ',
            'NOTDICT,NOTDIC'              : '[[WP:NOT|Wikipedia is not a dictionary]] (but [[Wiktionary]] is) ',
            'NOTMEMORIAL'                 : '[[WP:NOT|Wikipedia is not a memorial]] ',
            'NOTOR,NOTORIGINAL'           : '[[WP:NOT|Wikipedia is not a publisher of original thought]] ',
            'NOTSOAPBOX'                  : '[[WP:NOT|Wikipedia is not a soapbox]] ',
            'NOTSW,NOTSWDIR'              : '[[WP:NOT|Wikipedia is not a software directory]] ',
            'NOTWEBHOST,NOTFREEHOST'      : '[[WP:NOT|Wikipedia is not a free host or webspace provider]] ',
            'NOTWEBDIR'                   : '[[WP:NOT|Wikipedia is not a web directory]] ',
            'NFT,NOTSCHDAY,NOTSCH'        : '[[WP:NFT|Wikipedia is not for things made up in school one day]] ',
            'XBIO,BIOX'                   : 'Recommend the article author see [http://www.wikime.org/ WikiMe] for writing biographies and/or [http://www.wikitree.org WikiTree] for writing genealogies ',
            'XUSERFY,USERFYX'             : 'Article author may want to consider moving the content to his [[Wikipedia:User page|user page]] ',
            'XPROTO,XPROTOLOGISM,PROTOX'  : 'Protologisms may deserve listing at [[Wiktionary:List_of_protologisms]] ',
            'BALLS,BALL'                  : '[[WP:BALLS|Complete bollocks]]'
            });

function afd_vote_load() {
    if (afdLogP) {
        // log page
        afd_vote_annotate_afd();
    } else if (afdP) {
        // AFD page
        afd_vote_annotate_afd();
        addTab('javascript:afd_vote_this_page()', 'vote', 'ca-vote', "Vote on this AFD");
    } else {
        afd_vote_annotate_article();
    }
}

function afd_vote_annotate_article() {
    // is this a regular article that has an AFD notice?
    var afd = document.getElementById('afd');
    if (!afd) return;

    var anchors = copyArray(afd.getElementsByTagName('a'));
    var href = 'javascript:afd_vote_this_page()';

    for (i in anchors) {
        if (anchors[i].text == "this article's entry" &&
            anchors[i].href.match(/Wikipedia:Articles_for_deletion\/.*/))
        {
            add_after(anchors[i], document.createTextNode("] "));
            add_after(anchors[i], createHref(href, 'Vote on deletion of '+wikiPage.page, 'vote'));
            add_after(anchors[i], document.createTextNode(" ["));
            break;
        }
    }

    addTab(href, 'vote', 'ca-vote', 'Vote on AFD for this page');
}

function afd_vote_annotate_afd() {
    var url_re = /(\/w\/index.php\?title=Wikipedia:Articles_for_deletion\/([^&]+))&action=edit&/;
    var url, matches;
    window.sectionDivs = getElementsByClass('editsection', document.getElementById('bodyContent'), 'div');
    window.labeledSectionDivs = {};

    for (var i in sectionDivs) {
        var div = sectionDivs[i];
        div.i = i;
        var anchor = div.getElementsByTagName('a')[0];
        if (!( anchor.text == "edit"
               && (matches = anchor.href.match(url_re))
               && (matches[2].substr(0, 4) != 'Log/')) )
            continue;
        var title = ""+unescape(matches[2]).replace(/_/g,' ');

        // setup for easy lookup and traversal later
        labeledSectionDivs[title] = div;

        var closed = Boolean(anchor.parentNode.parentNode.getAttribute('class')=='boilerplate metadata vfd');

        if (!closed) {
            var vote_href = "javascript:afd_vote_page("+string_quote_escape(title)+")";
            add_after(anchor, createHref(vote_href, 'Vote on deletion of '+title, 'vote'));
            add_after(anchor, document.createTextNode("] ["));
        }
        var log_href = "/w/index.php?title=Special:Log&page=" + wpaescape(title);
        add_before(anchor, createHref(log_href, title, 'log'));
        add_before(anchor, document.createTextNode("] ["));
        var afd_href = matches[1];
        add_before(anchor, createHref(afd_href, title, 'afd'));
        add_before(anchor, document.createTextNode("] ["));
    }
}

// return true if string ends with period (can also have symbols such as closing paren after period)
function ends_with_period(str) {
    return Boolean(str.match(/[.?!][^a-zA-Z]*$/));
}

// return true if comment needs to be prefixed by 'as '
function afd_vote_comment_needs_as(comment) {
    var m = comment.match(/^([a-zA-Z]+)(.*)$/);
    var word1 = m && m[1];
    if (!word1) return false;
    if (word1 == 'or') return false; // special case for lowercase 'or'
    if (word1.toUpperCase() == 'PN') return false; // special case for 'PN'
    return afd_comment_shortcuts.substP(word1);
}

function afd_vote_expand_vote(vote) {
    vote = afd_vote_shortcuts.substFirstWord(vote);
    vote = afd_vote_shortcuts.substUppercaseWords(vote);
    return vote;
}

function afd_vote_expand_comment(vote, comment) {
    // if first word is a shortcut other than 'per nomination', prefix with 'as'

//    var need_as = afd_vote_comment_needs_as(comment);

    comment = afd_comment_shortcuts.substUppercaseWords(comment);
    if (!comment.match(/^or /)) {
        // "or" is too common as first word... use uppercase "OR" if that's intended.
        comment = afd_comment_shortcuts.substFirstWord(comment);
    }

/*
    if (need_as) {
        comment = 'as ' + comment;
    }
*/

    if (!ends_with_period(comment)) {
        comment += ".";
    }

    // prefix with space if necessary
    if (!comment.match(/^[.,:; ]/)) {
        comment = " " + comment;
        if (vote == 'Comment') comment = ":" + comment;
    }

    // common mistake
    comment = comment.replace(/{{(nn-?bio|nn-?band|db-attack|db-repost)}}/, '{{tl|$1}}');

    return comment;
}

function afd_vote_comment_possibly_unexpanded(comment) {
    // did user typo one of the shortcuts?
    return comment.match(/[A-Z][A-Z][A-Z]+(?![\]A-Z\|])/);
}

function afd_vote_this_page() {
    afd_vote(wikiPage);
}

function afd_vote_page(page) {
    afd_vote(new WikiPage(null,page));
}

function afd_vote(wp) {
    wp = wp.afdPageX();
    if (!(wp instanceof WikiPage)) { alert("## internal error bfc4b745-0e83-4e9a-9a16-7107c8e046ef: afd_vote: not a WikiPage"); return; }
    var vote0 = window.prompt("Enter your vote.   " + afd_vote_shortcuts.msg());
    if (!vote0) return;
    var vote = afd_vote_expand_vote(vote0);
    var vote_used_shortcut = (vote != vote0);

    var comment0prev;
    var comment0 = '';
    var comment;
    var pr = "Enter your comment.  ";

    while(true) {
        comment0 = window.prompt(pr + afd_comment_shortcuts.msg(), comment0);
        if (typeof comment0 != 'string') return;
        comment = afd_vote_expand_comment(vote, comment0);

        if (comment0 != comment0prev &&
            afd_vote_comment_possibly_unexpanded(comment))
        {
            comment0prev = comment0;
            pr = "Did you really mean '"+RegExp.lastMatch+"'?  Correct if you want.  ";
            continue;
        }
        break;
    }

    var default_summary = vote;
    var summary;

    if (afd_vote_summary_prompt && !vote_used_shortcut) {
        summary = window.prompt("Enter the edit summary:", default_summary);
        if (typeof summary != 'string') return;
    }
    summary = summary || default_summary;

    var newtext = "* '''"+vote+"'''"+comment+" " + makeSignature();
    wp.getEditorAsync(afd_vote_edit, newtext, summary);
}

function afd_vote_edit(editor, newtext, summary) {
    if (editor.refuseCreate()) return;

    editor.wpTextbox1 = trim_lines(editor.wpTextbox1) + '\n' + newtext;
    editor.wpSummary += summary;

    // are we at a log page?  (Note that 'window.location.href' is not as good as wikiPage because of shortcut redirects such as [[WP:AFD/Today]])

    var title = editor.wp.afdTargetPage().page;
    if (!title) {
        alert("## afd_vote_edit: bad page name");
    }

    var div, sec_end;
    if (afdP || afdLogP) {
        // show status if we're on an AFD or AFD Log page
        if (afdLogP) {
            div = labeledSectionDivs[title];
            if (!div) { alert("## No labeledSectionDivs['"+title+"']"); return; }
            sec_end = sectionDivs[parseInt(div.i)+1];
            // if the next entry is a closed discussion then we need to go one node up the tree
            if (sec_end.parentNode.id != 'bodyContent') sec_end = sec_end.parentNode;
        } else {
            sec_end = getElementsByClass('printfooter', document, 'div')[0];
        }
        var statusDiv = document.createElement('div');
        statusDiv.innerHTML = "<i>(submitting...)</i>";
        add_before( sec_end, statusDiv );
    }

    if (afdLogP) {
        // We're looking at a log page.  Submit this asynchronously and replace
        // the content of this section of the log page with new content.

        editor.submitAsync(null, afd_vote_log_update, div, sec_end);
    } else {
        // submit and go to changed page
        editor.submit();
    }
}

function afd_vote_log_update(req, div, sec_end) {
    if (req.status != 200) { alert ("Error submitting vote!"); return; }
    if (!div || !sec_end) { alert ("## afd_vote_log_update error"); return; }

    // Replace nodes between div and next div with new content.
    // Start at the <h3> tag, because the afd page text doesn't have a
    // section number (1.123), but the log text does.
    var newnodes_start = getElementsByClass('editsection', req.responseXML, 'div')[0].nextSibling.nextSibling.nextSibling.nextSibling.nextSibling;
    var newnodes_end = getElementsByClass('printfooter', req.responseXML, 'div')[0];
    var replacement_nodes = getNodesInRange(newnodes_start, newnodes_end);
    var newnode = document.createElement('div');
    for (i in replacement_nodes) { newnode.appendChild(replacement_nodes[i]); }

    var oldnodes_start = div.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling;
    removeNodesInRange(oldnodes_start, sec_end);
    add_after(div.nextSibling.nextSibling.nextSibling.nextSibling, newnode);
}

$(afd_vote_load);

//</nowiki></pre>