// ] - AFD auto-voting and shortcuts
// depends: wikipage.js, wikipageAfd.js, wikiedit.js, util.js, shortcuts.js, datestamp.js
// enhanced by: advanced_sig.js
// originally based on http://en.wikipedia.orghttps://wikines.com/en/User:Jnothman/afd_helper/script.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 "~~~~"};
afd_vote = new Object();
afd_vote.summary_prompt = true;
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' : ']',
'SPK' : 'Speedy keep',
'C' : 'Comment',
'MC' : 'Metacomment',
'BJAODN,BJ' : 'BJAODN'
});
afd_vote.comment_shortcuts = Shortcuts( {
'PN' : 'per nomination',
'NN' : ']',
'V,VAIN,VANITY' : ']',
'NNBIO' : ']',
'NNVBIO' : ']',
'NNWEB' : ']',
'NNWEBCOMIC ' : ']',
'NNBLOG,NNWEBLOG' : '] ',
'NNFORUM,NNWEBFORUM' : '] ',
'NNSOFTWARE,NNSOFT,NNSW' : '] ',
'NNCORP,NNCOMPANY' : ']',
'NNMUSIC' : ']',
'NNBAND' : ']',
'NNUNEO' : ']',
'NNUUNEO' : ']',
'NNFICT,NNFICTION' : ']',
'NNFICTC,NNFICTCHAR,NNCHAR' : '] ',
'FANCRUFT,NNFAN' : ']',
'NNFANFIC' : ']',
'NNGAME' : '] online gaming group',
'U' : ']',
'UPH' : '], possible ]',
'OR' : ']',
'UOR' : '] and/or ]',
'H' : ']',
'HSANC,HSANCT,HSANCTION' : '], and sanction article author',
'ATTACK' : ']',
'WISHSP,WISHEXPAND' : 'I wish for expansion of ] so that this kind of article could be speedy-deleted when no notability is asserted ',
'UNENC,UNENCYCLO,NOTPEDIC' : ']',
'NOT' : ']',
'NOTADVERT' : '] ',
'NOTBALL,NOTCRYSTAL' : '] ',
'NOTCRUFT' : '] ',
'NOTDICT,NOTDIC' : '] (but ] is) ',
'NOTMEMORIAL' : '] ',
'NOTOR,NOTORIGINAL' : '] ',
'NOTSOAPBOX' : '] ',
'NOTSW,NOTSWDIR' : '] ',
'NOTWEBHOST,NOTFREEHOST' : '] ',
'NOTWEBDIR' : '] ',
'NFT,NOTSCHDAY,NOTSCH' : '] ',
'XBIO,BIOX' : 'Recommend the article author see for writing biographies and/or for writing genealogies ',
'XUSERFY,USERFYX' : 'Article author may want to consider moving the content to his ] ',
'XPROTO,XPROTOLOGISM,PROTOX' : 'Protologisms may deserve listing at ] ',
'BALLS,BALL' : ']'
});
afd_vote._load = function() {
if (afdLogP) {
// log page
afd_vote.annotateAfd();
} else if (afdP) {
// AFD page
afd_vote.annotateAfd();
addTab('javascript:afd_vote.doVote()', 'vote', 'ca-vote', "Vote on this AFD");
} else {
afd_vote.annotateArticle();
}
}
afd_vote.annotateArticle = function() {
// is this a regular article that has an AFD notice?
var afd = document.getElementById('afd');
if (!afd) return;
var href = 'javascript:afd_vote.doVote()';
var title = 'Vote on deletion of '+wikiPage.page;
var anchors = copyArray(afd.getElementsByTagName('a'));
for (i in anchors) {
if (anchors.text == "this article's entry" &&
anchors.href.match(/Wikipedia:Articles_for_deletion\/.*/))
{
var span = document.createElement('span');
span.innerHTML = ' ';
add_after(anchors, span);
break;
}
}
addTab(href, 'vote', 'ca-vote', title);
}
afd_vote.annotateAfd = function() {
var url_re = /(\/w\/index.php\?title=Wikipedia:Articles_for_deletion\/(+))&action=edit&/;
var url, matches;
afd_vote.sectionDivs = getElementsByClass('editsection', document.getElementById('bodyContent'), 'div');
afd_vote.labeledSectionDivs = {};
for (var i in afd_vote.sectionDivs) {
var div = afd_vote.sectionDivs;
div.i = i;
var anchor = div.getElementsByTagName('a');
if (!( anchor.text == "edit"
&& (matches = anchor.href.match(url_re))
&& (matches.substr(0, 4) != 'Log/')) )
continue;
var title = ""+unescape(matches).replace(/_/g,' ');
// setup for easy lookup and traversal later
afd_vote.labeledSectionDivs = div;
var closed = Boolean(anchor.parentNode.parentNode.getAttribute('class')=='boilerplate metadata vfd');
if (!closed) {
var vote_href = "javascript:afd_vote.doVote("+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;
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)
afd_vote._ends_with_period = function(str) {
return Boolean(str.match(/*$/));
}
// return true if comment needs to be prefixed by 'as '
afd_vote._comment_needs_as = function(comment) {
var m = comment.match(/^(+)(.*)$/);
var word1 = m && m;
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_vote.comment_shortcuts.substP(word1);
}
afd_vote.expand_vote = function(vote) {
vote = afd_vote.shortcuts.substFirstWord(vote);
vote = afd_vote.shortcuts.substUppercaseWords(vote);
return vote;
}
afd_vote.expand_comment = function(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_vote.comment_shortcuts.substUppercaseWords(comment);
if (!comment.match(/^or /)) {
// "or" is too common as first word... use uppercase "OR" if that's intended.
comment = afd_vote.comment_shortcuts.substFirstWord(comment);
}
if (need_as) {
comment = 'as ' + comment;
}
if (!afd_vote._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;
}
afd_vote._comment_possibly_unexpanded = function(comment) {
// did user typo one of the shortcuts?
return comment.match(/+(?!A-Z\|])/);
}
afd_vote.doVote = function(pagename) {
if (pagename) {
afd_vote.doVoteWP(new WikiPage(null,pagename));
} else {
afd_vote.doVoteWP(wikiPage);
}
}
afd_vote.doVoteWP = function(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_vote.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 '"+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);
}
afd_vote._edit = function(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 ])
var title = editor.wp.afdTargetPage().page;
if (!title) {
alert("## afd_vote._edit: bad page name (error b2e39d30-fd3d-405e-adf1-5f0c7c034e53)");
}
var div, sec_end;
if (afdP || afdLogP) {
// show status if we're on an AFD or AFD Log page
if (afdLogP) {
div = afd_vote.labeledSectionDivs;
if (!div) { alert("## No labeledSectionDivs"); return; }
sec_end = afd_vote.sectionDivs;
if (!sec_end) {
// No next entry, must be end of page. Add an empty div.
sec_end = document.createElement('div');
div.parentNode.appendChild(sec_end);
} else if (sec_end.parentNode.id != 'bodyContent') {
// if the next entry is a closed discussion then we need to go
// one node up the tree
sec_end = sec_end.parentNode;
}
} else {
sec_end = getElementsByClass('printfooter', document, 'div');
}
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();
}
}
afd_vote.log_update = function(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').nextSibling.nextSibling.nextSibling.nextSibling.nextSibling;
var newnodes_end = getElementsByClass('printfooter', req.responseXML, 'div');
var replacement_nodes = getNodesInRange(newnodes_start, newnodes_end);
var newnode = document.createElement('div');
for (i in replacement_nodes) { newnode.appendChild(replacement_nodes); }
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>