User:Alanl/mergeHelper2.js

////////////////////////////////////////////

//

// Yet another AfC helper script

// v.4.1.0

// Adapted from User:Mr.Z-man/closeAFD

//

////////////////////////////////////////////

//

if (wgPageName.indexOf('Wikipedia:Articles_for_creation/Redirects') != -1) {

var mergeHelper_RedirectPageName = wgPageName.replace(/_/g, ' ');

var mergeHelper_RedirectSubmissions = new Array();

var mergeHelper_RedirectSections = new Array();

var mergeHelper_numTotal = 0;

var mergeHelper_Redirect_AJAXnumber = 0;

var mergeHelper_Submissions = new Array();

var mergeHelper_redirectDecline_reasonhash = {

'exists' : 'The title you suggested already exists on Wikipedia',

'blank' : 'We cannot accept empty submissions',

'notarget': ' A redirect cannot be created unless the target is an existing article. Either you have not specified the target, or the target does not exist',

'unlikely': 'The title you suggested seems unlikely. Could you provide a source showing that it is a commonly used alternate name?',

'notredirect': 'This request is not a redirect request',

'custom': ''

};

var mergeHelper_categoryDecline_reasonhash = {

'exists' : 'The category you suggested already exists on Wikipedia',

'blank' : 'We cannot accept empty submissions',

'unlikely': 'It seems unlikely that there are enough pages to support this category',

'notcategory':'This request is not a category request',

'custom': ''

};

function mergeHelper_redirect_init(){

mergeHelper_RedirectSubmissions = new Array();

mergeHelper_RedirectSections = new Array();

mergeHelper_numTotal = 0;

var pagetext = mergeHelper_redirect_getPageText(mergeHelper_RedirectPageName, false);

// let the parsing begin.

// first, strip out the parts before the first section.

var section_re = /==[^=]*==/;

pagetext = pagetext.substring(pagetext.search(section_re));

// second, strip out the parts that has been mass-moderated.

// first find the place of mass moderation

var mass_re = /\{\{(?:(?:afc-c|afc top)\|\s*m|afc mm)/i;

if(mass_re.test(pagetext)){

var mass_mods = mass_re.exec(pagetext);

for(var i = 0; i < mass_mods.length; i++){

var mass_mod_start = pagetext.indexOf(mass_mods[i]);

var mass_mod_end = pagetext.substring(mass_mod_start).search(/\{\{(?:afc-c\|\s*b|afc b)/i);

mass_mod_end += mass_mod_start;

mass_mod_end = pagetext.indexOf('\}\}', mass_mod_end);

pagetext = pagetext.substring(0, mass_mod_start) + pagetext.substring(mass_mod_end + 2);

}

}

// now parse it into sections.

section_re = /==[^=]*==/g;

var section_headers = pagetext.match(section_re);

for(var i = 0; i < section_headers.length; i++){

var section_start = pagetext.indexOf(section_headers[i]);

var section_text = pagetext.substring(section_start);

if(i < section_headers.length-1){

var section_end = section_text.substring(section_headers[i].length).indexOf(section_headers[i+1]) + section_headers[i].length;

section_text = section_text.substring(0, section_end);

}

mergeHelper_RedirectSections.push(section_text);

}

// parse the sections.

for(var i = 0; i < mergeHelper_RedirectSections.length; i++){

var closed = /\{\{\s*afc(?!\s+comment)/i.test(mergeHelper_RedirectSections[i]);

if(!closed){

// parse.

var header = mergeHelper_RedirectSections[i].match(section_re)[0];

if(header.search(/Redirect request/i) != -1){

var wikilink_re = /\[\^\[\+\]\]/g;

var links = header.match(wikilink_re);

if(!links) continue;

for(var j = 0; j < links.length; j++){

links[j]=links[j].replace(/[\[\]]/g, '');

if(links[j].charAt(0) == ':')

links[j] = links[j].substring(1);

}

var re = /Target of redirect:\s*\[\[([^\[\]]*)\]\]/i;

re.test(mergeHelper_RedirectSections[i]);

var to = RegExp.$1;

var submission = {

type: 'redirect',

from: new Array(),

section: i,

to: to,

title: to

};

for(var j = 0; j < links.length; j++){

var sub = {

type: 'redirect',

to: to,

id: mergeHelper_numTotal,

title: links[j],

action: ''

};

submission.from.push(sub);

mergeHelper_Submissions.push(sub);

mergeHelper_numTotal++;

}

mergeHelper_RedirectSubmissions.push(submission);

}

else if(header.search(/Category request/i) != -1){

var wikilink_re = /\[\^\[\+\]\]/g;

var links = header.match(wikilink_re);

if(!links) continue;

// figure out the parent category.

var idx = mergeHelper_RedirectSections[i].substring(header.length).search(/\[\[\s*:\s*(Category:[^\]\[]*)\]\]/i);

var parent = '';

if(idx != -1)

parent = RegExp.$1;

parent = parent.replace(/:\s*/g, ':');

for(var j = 0; j < links.length; j++){

links[j]=links[j].replace(/[\[\]]/g, '');

links[j]=links[j].replace(/Category\s*:\s*/gi, 'Category:');

if(links[j].charAt(0) == ':')

links[j] = links[j].substring(1);

var submission = {

type: 'category',

title: links[j],

section: i,

id: mergeHelper_numTotal,

action: '',

parent: parent

};

mergeHelper_numTotal++;

mergeHelper_RedirectSubmissions.push(submission);

mergeHelper_Submissions.push(submission);

}

}

}

}

var text = '

Reviewing AFC redirect requests

';

// now layout the text.

for(var k = 0; k < mergeHelper_RedirectSubmissions.length; k++){

text += '

    ';

    if(mergeHelper_RedirectSubmissions[k].type == 'redirect'){

    text += '

  • Redirect(s) to

    + '">' + mergeHelper_RedirectSubmissions[k].to + ':

      ';

      for(var l = 0; l < mergeHelper_RedirectSubmissions[k].from.length; l++){

      var from = mergeHelper_RedirectSubmissions[k].from[l];

      text += "

    • From: " + from.title

      +'
      '

      + mergeHelper_redirect_generateSelect('mergeHelper_redirect_action_'+ from.id,

      [{ label: 'Accept', value: 'accept' },

      { label: 'Decline', value: 'decline' },

      { label: 'Comment', value: 'comment' },

      { label: 'None', selected : true, value: 'none' }

      ], 'mergeHelper_redirect_onActionChange(' + from.id + ')')

      + '

    • ';

      }

      text += '

  • ';

    }

    else{

    text += '

  • Category submission: '+ mergeHelper_RedirectSubmissions[k].title;

    text += '
    '

    + mergeHelper_redirect_generateSelect('mergeHelper_redirect_action_'+ mergeHelper_RedirectSubmissions[k].id,

    [{ label: 'Accept', value: 'accept' },

    { label: 'Decline', value: 'decline' },

    { label: 'Comment', value: 'comment' },

    { label: 'None', selected : true, value: 'none' }

    ], 'mergeHelper_redirect_onActionChange(' + mergeHelper_RedirectSubmissions[k].id + ')')

    + '

  • ';

    }

    text += '

';

}

text += '';

jsMsg(text);

}

function mergeHelper_redirect_onActionChange(id){

var extra = document.getElementById("mergeHelper_redirect_extra_" + id);

var selectValue = document.getElementById("mergeHelper_redirect_action_"+id).value;

if(selectValue == 'none')

extra.innerHTML = '';

else if(selectValue == 'accept'){

if(mergeHelper_Submissions[id].type == 'redirect'){

extra.innerHTML = '

'name="mergeHelper_redirect_from_' + id + '" id="mergeHelper_redirect_from_' + id + '" value="'

+ mergeHelper_Submissions[id].title + '" />';

extra.innerHTML += ' 

'name="mergeHelper_redirect_to_' + id + '" id="mergeHelper_redirect_to_' + id + '" value="'

+ mergeHelper_Submissions[id].to + '" />';

extra.innerHTML += ''

+ mergeHelper_redirect_generateSelect('mergeHelper_redirect_append_'+

id, [

{ label: 'R from alternative name', value: 'R from alternative name' },

{ label: 'R from alternative language', value: 'R from alternative language' },

{ label: 'R from alternative spelling', value: 'R from alternative spelling' },

{ label: 'R to section', value: 'R to section' },

{ label: 'R to disambiguation page', value: 'R to disambiguation page' },

{ label: 'R from title with diacritics', value: 'R from title with diacritics'},

{ label: 'Custom - prompt me', value: 'custom' },

{ label: 'None', selected : true, value: 'none' }

]);

}

else{

extra.innerHTML = '

'name="mergeHelper_redirect_name_' + id + '" id="mergeHelper_redirect_name_' + id + '" value="'

+ mergeHelper_Submissions[id].title + '" />';

extra.innerHTML += ''

+ '';

}

extra.innerHTML += ''

+ '';

} else if(selectValue == 'decline'){

if(mergeHelper_Submissions[id].type == 'redirect'){

extra.innerHTML = ''

+ mergeHelper_redirect_generateSelect('mergeHelper_redirect_decline_'+

id, [

{ label: 'Already exists', value: 'exists' },

{ label: 'Blank request', value: 'blank' },

{ label: 'No valid target specified', value: 'notarget' },

{ label: 'Unlikely search term', value: 'unlikely' },

{ label: 'Not a redirect request', value: 'notredirect' },

{ label: 'Custom - reason below', selected : true, value: 'custom' }

]);

}

else {

extra.innerHTML = ''

+ mergeHelper_redirect_generateSelect('mergeHelper_redirect_decline_'+

id, [

{ label: 'Already exists', value: 'exists' },

{ label: 'Blank request', value: 'blank' },

{ label: 'Unlikely category', value: 'unlikely' },

{ label: 'Not a category request', value: 'notcategory' },

{ label: 'Custom - reason below', selected : true, value: 'custom' }

]);

}

extra.innerHTML += ''

+ '';

} else{

extra.innerHTML = ''

+ '';

}

}

function mergeHelper_redirect_performActions(){

// Load all of the data.

for(var i = 0; i < mergeHelper_Submissions.length; i++){

var action = document.getElementById("mergeHelper_redirect_action_" + i).value;

mergeHelper_Submissions[i].action = action;

if(action == 'none')

continue;

if(action == 'accept'){

if(mergeHelper_Submissions[i].type == 'redirect'){

mergeHelper_Submissions[i].title = document.getElementById("mergeHelper_redirect_from_" + i).value;

mergeHelper_Submissions[i].to = document.getElementById("mergeHelper_redirect_to_" + i).value;

mergeHelper_Submissions[i].append = document.getElementById("mergeHelper_redirect_append_" + i).value;

if(mergeHelper_Submissions[i].append == 'custom'){

mergeHelper_Submissions[i].append = prompt("Please enter the template to append for " + mergeHelper_Submissions[i].title

+ ". Do not include the curly brackets.");

}

if(mergeHelper_Submissions[i].append == 'none' || mergeHelper_Submissions[i].append == null)

mergeHelper_Submissions[i].append = '';

else

mergeHelper_Submissions[i].append = '\{\{' + mergeHelper_Submissions[i].append + '\}\}';

}

else{

mergeHelper_Submissions[i].title = document.getElementById("mergeHelper_redirect_name_" + i).value;

mergeHelper_Submissions[i].parent = document.getElementById("mergeHelper_redirect_parent_" + i).value;

}

}

else if (action == 'decline'){

mergeHelper_Submissions[i].reason = document.getElementById('mergeHelper_redirect_decline_' + i).value;

}

mergeHelper_Submissions[i].comment = document.getElementById("mergeHelper_redirect_comment_" + i).value;

}

// Data loaded. Show progress screen and get edit token and WP:AFC/R page text.

jsMsg('

      ');

      document.getElementById('mergeHelper_finish').innerHTML += '

    • Done (Reload page)
    • ';

      var token = mergeHelper_redirect_getToken(true);

      var pagetext = mergeHelper_redirect_getPageText(mergeHelper_RedirectPageName, true);

      var totalaccept = 0;

      var totaldecline = 0;

      var totalcomment = 0;

      // traverse the submissions and locate the relevant sections.

      for(var i = 0; i < mergeHelper_RedirectSubmissions.length; i++){

      var sub = mergeHelper_RedirectSubmissions[i];

      if(pagetext.indexOf(mergeHelper_RedirectSections[sub.section]) == -1){

      // Someone has modified the section in the mean time. Skip.

      document.getElementById('mergeHelper_status').innerHTML += '

    • Skipping ' + sub.title + ': Cannot find section. Perhaps it was modified in the mean time?
    • ';

      continue;

      }

      var text = mergeHelper_RedirectSections[sub.section];

      var startindex = pagetext.indexOf(mergeHelper_RedirectSections[sub.section]);

      var endindex = startindex + text.length;

      // First deal with cats. These are easy.

      if(sub.type == 'category'){

      if(sub.action == 'accept'){

      var cattext = '';

      if(sub.parent != '' )

      cattext = '\[\['+ sub.parent + '\]\]';

      mergeHelper_redirect_editPage(sub.title, cattext, token, 'Created via \[\[WP:AFC|Articles for Creation\]\] (\[\[WP:WPAFC|you can help!\]\])', true);

      var talktext = '\{\{subst:WPAFC/article|class=Cat\}\}';

      var talktitle = sub.title.replace(/Category:/gi, 'Category talk:');

      mergeHelper_redirect_editPage(talktitle, talktext, token, 'Placing WPAFC project banner', true);

      var header = text.match(/==[^=]*==/)[0];

      text = header + "\n\{\{AfC-c|a\}\}\n" + text.substring(header.length);

      if(sub.comment != '')

      text += '\n*\{\{subst:afc category|accept|2=' + sub.comment +'\}\} \~\~\~\~\n';

      else

      text += '\n*\{\{subst:afc category\}\} \~\~\~\~\n';

      text += '\{\{AfC-c|b\}\}\n';

      totalaccept ++;

      }

      else if (sub.action == 'decline'){

      var header = text.match(/==[^=]*==/)[0];

      var reason = mergeHelper_categoryDecline_reasonhash[sub.reason];

      if(reason == '')

      reason = sub.comment;

      else if (sub.comment != '')

      reason = reason + ': ' + sub.comment;

      if(reason == ''){

      document.getElementById('mergeHelper_status').innerHTML += '

    • Skipping ' + sub.title + ': No decline reason specified.
    • ';

      continue;

      }

      text = header + "\n\{\{AfC-c|d\}\}\n" + text.substring(header.length);

      if(sub.comment == '')

      text += '\n*\{\{subst:afc category|' + sub.reason +'\}\} \~\~\~\~\n';

      else

      text += '\n*\{\{subst:afc category|decline|2=' + reason +'\}\} \~\~\~\~\n';

      text += '\{\{AfC-c|b\}\}\n';

      totaldecline++;

      }

      else if (sub.action == 'comment'){

      if(sub.comment != '')

      text += '\n*\{\{afc comment|1=' + sub.comment +'\~\~\~\~\}\}\n';

      totalcomment++;

      }

      }

      else {

      // redirects......

      var acceptcomment = '';

      var declinecomment = '';

      var othercomment = '';

      var acceptcount = 0, declinecount = 0, commentcount = 0, hascomment = false;

      for(var j = 0; j < sub.from.length; j++){

      var redirect = sub.from[j];

      if(redirect.action == 'accept'){

      var redirecttext = '#REDIRECT \[\[' + redirect.to + '\]\]\n' + redirect.append;;

      mergeHelper_redirect_editPage(redirect.title, redirecttext, token, 'Created via \[\[WP:AFC|Articles for Creation\]\] (\[\[WP:WPAFC|you can help!\]\])', true);

      var talktext = '\{\{subst:WPAFC/redirect\}\}';

      var talktitle = 'Talk:' + redirect.title;

      mergeHelper_redirect_editPage(talktitle, talktext, token, 'Placing WPAFC project banner', true);

      acceptcomment += redirect.title + " → " + redirect.to;

      if(redirect.comment != ''){

      acceptcomment += ': ' + redirect.comment + '; ';

      hascomment = true;

      } else

      acceptcomment += '; ';

      acceptcount ++;

      }

      else if (redirect.action == 'decline'){

      var reason = mergeHelper_redirectDecline_reasonhash[redirect.reason];

      if(reason == '')

      reason = redirect.comment;

      else if (redirect.comment != '')

      reason = reason + ': ' + redirect.comment;

      if(reason == ''){

      document.getElementById('mergeHelper_status').innerHTML += '

    • Skipping ' + redirect.title + ': No decline reason specified.
    • ';

      continue;

      }

      declinecomment += redirect.title + " → " + redirect.to + ": " + reason + "; ";

      declinecount ++;

      }

      else if (redirect.action == 'comment'){

      othercomment += redirect.title + ": " + redirect.comment + ", ";

      commentcount ++;

      }

      }

      var reason = '';

      if(acceptcount > 0)

      reason += '\n*\{\{subst:afc redirect|accept|2=' + acceptcomment + ' Thank you for your contributions to Wikipedia!\}\} \~\~\~\~';

      if (declinecount > 0)

      reason += '\n*\{\{subst:afc redirect|decline|2=' + declinecomment + '\}\} \~\~\~\~';

      if(commentcount > 0)

      reason += '\n*\{\{afc comment|1=' + othercomment + '\~\~\~\~\}\}';

      reason += '\n';

      if(!hascomment && acceptcount == sub.from.length){

      if(acceptcount > 1)

      reason = '\n*\{\{subst:afc redirect|all\}\} \~\~\~\~\n';

      else

      reason = '\n*\{\{subst:afc redirect\}\} \~\~\~\~\n';

      }

      if(acceptcount + declinecount + commentcount > 0){

      if(acceptcount + declinecount == sub.from.length){

      // Every request disposed of. Close.

      var header = text.match(/==[^=]*==/)[0];

      if(acceptcount > declinecount)

      text = header + "\n\{\{AfC-c|a\}\}\n" + text.substring(header.length);

      else

      text = header + "\n\{\{AfC-c|d\}\}\n" + text.substring(header.length);

      text += reason;

      text += '\{\{AfC-c|b\}\}\n';

      }

      else

      text += reason +'\n';

      }

      totalaccept += acceptcount;

      totaldecline += declinecount;

      totalcomment += commentcount;

      }

      pagetext = pagetext.substring(0, startindex) + text + pagetext.substring(endindex);

      }

      var summary = "Updating submission status:";

      if(totalaccept > 0)

      summary += " accepting " + totalaccept + " request" + (totalaccept > 1 ? 's' : '');

      if(totaldecline > 0){

      if(totalaccept > 0)

      summary += ',';

      summary += " declining " + totaldecline + " request" + (totaldecline > 1 ? 's' : '');

      }

      if(totalcomment > 0){

      if(totalaccept > 0 || totaldecline > 0)

      summary += ',';

      summary += " commenting on " + totalcomment + " request" + (totalcomment > 1 ? 's' : '');

      }

      mergeHelper_redirect_editPage(mergeHelper_RedirectPageName, pagetext, token, summary, false);

      document.getElementById('mergeHelper_finished_main').style.display = '';

      }

      function mergeHelper_redirect_getToken(show) {

      if (show) {

      document.getElementById('mergeHelper_status').innerHTML += '

    • Getting token
    • ';

      }

      var req = sajax_init_object();

      req.open("GET", wgScriptPath + "/api.php?action=query&prop=info&indexpageids=1&intoken=edit&format=json&titles="+encodeURIComponent(mergeHelper_RedirectPageName), false);

      req.send(null);

      var response = eval('(' + req.responseText + ')');

      pageid = response['query']['pageids'][0];

      token = response['query']['pages'][pageid]['edittoken'];

      delete req;

      if (show) {

      document.getElementById('mergeHelper_gettoken').innerHTML = 'Got token';

      }

      return token;

      }

      function mergeHelper_redirect_editPage(title, newtext, token, summary, createonly) {

      document.getElementById('mergeHelper_finished_wrapper').innerHTML = '';

      var func_id = mergeHelper_Redirect_AJAXnumber;

      mergeHelper_Redirect_AJAXnumber++;

      document.getElementById('mergeHelper_status').innerHTML += '

    • Editing '+title+'
    • ';

      var req = sajax_init_object();

      var params = "action=edit&format=json&token="+encodeURIComponent(token)+"&title="+encodeURIComponent(title)+"&text="+encodeURIComponent(newtext)+"¬minor=1&summary="+encodeURIComponent(summary);

      if(createonly)

      params += "&createonly=1";

      url = wgScriptPath + "/api.php";

      req.open("POST", url, true);

      req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

      req.setRequestHeader("Content-length", params.length);

      req.setRequestHeader("Connection", "close");

      req.onreadystatechange = function() {

      if(req.readyState == 4 && req.status == 200) {

      response = eval('(' + req.responseText + ')');

      try {

      if (response['edit']['result'] == "Success") {

      document.getElementById('mergeHelper_edit'+escape(title)).innerHTML = 'Saved '+title+'';

      } else {

      document.getElementById('mergeHelper_edit'+escape(title)).innerHTML = '

      Edit failed on '+title+'
      . Error info:' +response['error']['code'] + ' : ' + response['error']['info'];

      }

      }

      catch(err) {

      document.getElementById('mergeHelper_edit'+escape(title)).innerHTML = '

      Edit failed on '+title+'
      ';

      }

      document.getElementById('mergeHelper_AJAX_finished_'+func_id).style.display = '';

      delete req;

      }

      };

      req.send(params);

      }

      function mergeHelper_redirect_getPageText(title, show) {

      if(show){

      document.getElementById('mergeHelper_status').innerHTML += '

    • Getting '+title+'
    • ';

      }

      var req = sajax_init_object();

      req.open("GET", wgScriptPath + "/api.php?action=query&prop=revisions&rvprop=content&format=json&indexpageids=1&titles="+encodeURIComponent(title), false);

      req.send(null);

      var response = eval('(' + req.responseText + ')');

      pageid = response['query']['pageids'][0];

      if (pageid == "-1") {

      if(show){

      document.getElementById('mergeHelper_get'+escape(title)).innerHTML = ''+title+' does not exist';

      }

      delete req;

      return '';

      }

      pagetext = response['query']['pages'][pageid]['revisions'][0]['*'];

      delete req;

      if(show){

      document.getElementById('mergeHelper_get'+escape(title)).innerHTML = 'Got '+title+'';

      }

      return pagetext;

      }

      function mergeHelper_redirect_generateSelect(title, options, onchange){

      var text = '";

      return text;

      }

      function mergeHelper_redirect_addLink() {

      addPortletLink("p-cactions", "javascript:mergeHelper_redirect_init()", "Review", "ca-mergeHelper", "Review");

      }

      addOnloadHook(mergeHelper_redirect_addLink);

      }

      else if (wgNamespaceNumber == 1) {

      var mergeHelper_PageName = wgPageName.replace(/_/g, ' ');

      var mergeHelper_AJAXnumber = 0;

      var mergeHelper_submissionTitle = wgTitle.replace(/Articles for creation\//g, '');

      var mergeHelper_reasonhash = {

      'v': 'submission is unsourced or contains only unreliable sources',

      'blank': 'submission is blank',

      'lang': 'submission is not in English',

      'cv': 'submission is a copyright violation',

      'exists': 'submission already exists in main space',

      'dup': 'submission is a duplicate of another submission',

      'redirect': 'submission is a redirect request',

      'test': 'submission is a test edit',

      'news': 'submission appears to be a news report of a single event',

      'dict': 'submission is a dictionary definition',

      'joke': 'submission appears to be a joke',

      'blp': 'submission does not conform to BLP',

      'neo': 'submission is a neologism',

      'npov': 'submission is not written from a neutral point of view',

      'adv': 'submission is written like an advertisement',

      'context': 'submission provides insufficient context',

      'mergeto': 'submission is too short but can be merged',

      'plot': 'submission is a plot summary',

      'essay': 'submission reads like an essay',

      'not': 'submission is covered by WP:NOT',

      'nn': 'subject appears to be non-notable',

      'web': 'subject appears to be non-notable web content',

      'prof': 'subject appears to be a non-notable academic',

      'athlete': 'subject appears to be a non-notable athlete',

      'music': 'subject appears to be a non-notable musical performer or work',

      'film': 'subject appears to be a non-notable film',

      'corp': 'subject appears to be a non-notable company or organization',

      'bio': 'subject appears to be a non-notable person',

      'reason': ''

      };

      function mergeHelper_init() {

      if (!wfSupportsAjax()) {

      jsMsg('Your browser does not seem to support AJAX, which is required for the mergeHelper script v3.');

      return;

      }

      form = '

      '+

      '

      Page Merge helper

      '+

      ''+

      ''+

      /*''+*/

      ''+

      ''+

      '

      ';

      jsMsg(form);

      }

      function mergeHelper_prompt(type) {

      if(type == 'propose'){

      var msg1 = "";

      var text = '

      Proposing Article Merge

      '+

      ''+

      '
      ';

      text += '
      '+

      '
      ';

      document.getElementById('mergeHelper_extra').innerHTML += text;

      }

      if(type == 'accept'){ //TODO: Should automatically figure out where to move from and stop if a merger proposal is not there.

      var text = '

      Accepting Merge proposal

      '+

      ''+

      '
      '+

      '
      ';

      document.getElementById('mergeHelper_extra').innerHTML += text;

      }

      else if(type == 'decline' || type == 'hold'){

      var text = '

      ' + (type == 'decline' ? 'Declining ' : 'Placing on hold ') +mergeHelper_PageName+'

      '+

      '';

      var reasonSelect = mergeHelper_generateSelect("mergeHelper_reason",

      [{ label: 'v - submission is unsourced or contain only unreliable sources', value: 'v' },

      { label: 'blank - submission is blank', value: 'blank' },

      { label: 'lang - submission is not in English', value: 'lang' },

      { label: 'cv - submission is a copyright violation', value: 'cv' },

      { label: 'exists - submission already exists in main space', value: 'exists' },

      { label: 'dup - submission is a duplicate of another submission', value: 'dup' },

      { label: 'redirect - submission is a redirect request', value: 'redirect' },

      { label: 'test - submission is a test edit', value: 'test' },

      { label: 'news - submission appears to be a news report of a single event', value: 'news' },

      { label: 'dict - submission is a dictionary definition', value: 'dict' },

      { label: 'joke - submission appears to be a joke', value: 'joke' },

      { label: 'blp - submission does not conform to BLP', value: 'blp' },

      { label: 'neo - submission is a neologism', value: 'neo' },

      { label: 'npov - submission is not written from a neutral point of view', value: 'npov' },

      { label: 'adv - submission is written like an advertisement', value: 'adv' },

      { label: 'context - submission provides insufficient context', value: 'context' },

      { label: 'mergeto - submission is too short but can be merged', value: 'mergeto' },

      { label: 'plot - submission is a plot summary', value: 'plot' },

      { label: 'essay - submission reads like an essay', value: 'essay' },

      { label: 'not - submission is covered by WP:NOT', value: 'not' },

      { label: 'nn - subject appears to be non-notable - consider using a more specialized decline reason', value: 'nn' },

      { label: 'web - subject appears to be non-notable web content', value: 'web' },

      { label: 'prof - subject appears to be a non-notable academic', value: 'prof' },

      { label: 'athlete - subject appears to be a non-notable athlete', value: 'athlete' },

      { label: 'music - subject appears to be a non-notable musical performer or work', value: 'music' },

      { label: 'film - subject appears to be a non-notable film', value: 'film' },

      { label: 'corp - subject appears to be a non-notable company or organization', value: 'corp' },

      { label: 'bio - subject appears to be a non-notable person', value: 'bio' },

      { label: 'Custom - reason below', selected : true, value: 'reason' }

      ], "mergeHelper_onChange(this)");

      text += reasonSelect;

      text += '
      '+

      '
      ' +

      '
      ';

      document.getElementById('mergeHelper_extra').innerHTML += text;

      }

      else if(type == 'comment'){

      var text = '

      Commenting on ' +mergeHelper_PageName+'

      '+

      '
      ';

      document.getElementById('mergeHelper_extra').innerHTML += text;

      }

      document.getElementById('mergeHelper_extra').innerHTML += '';

      }

      function mergeHelper_act(action) {

      var destTitle = wgTitle;

      var sourceTitle = document.getElementById("mergeHelper_movesource").value;

      var sourceText;

      var destText;

      var destTalkText;

      destTitle = destTitle.replace(/_/g, ' ');

      sourceTitle = sourceTitle.replace(/_/g, ' '); // remove underscores from Article Titles

      //var assessment = document.getElementById("mergeHelper_assessment").value;

      var pageAppend = document.getElementById("mergeHelper_pageAppend").value;

      var talkAppend = document.getElementById("mergeHelper_talkAppend").value;

      //TODO: check that sourceTitle exists or abort

      jsMsg('

          ');

          document.getElementById('mergeHelper_finish').innerHTML += '

        • Done (Reload page)
        • ';

          var token = mergeHelper_getToken(true);

          if (action =='propose'){

          var destTalkPage = mergeHelper_getPageText('talk:'+destTitle);

          var destMergerTemplate = '{{Merge from|' +sourceTitle +'|discuss=Talk:' +destTitle +'#Merger proposal|date=' +mergeHelper_nowMonthYear() +'}}\n';

          var destSourceTemplate = '{{Merge to|' +destTitle +'|discuss=Talk:' +destTitle +'#Merger proposal|date=' +mergeHelper_nowMonthYear() +'}}\n';

          var mergeReason = "\n\n== Merger proposal ==\n\nI propose that " +sourceTitle + " be merged into " + destTitle + ". I think that the content in the " +sourceTitle + " article can easily be explained in the context of " + destTitle + ", and the " + sourceTitle + " article is of a reasonable size in which the merging of "+ destTitle+" will not cause any problems as far as article size or undue weight is concerned.\x7e\x7e\x7e\x7e";

          //destTalkPage = destMergerTemplate +destTalkPage;

          destTalkPage += mergeReason;

          var editSummary = "Propose that " +sourceTitle + " be merged into " + destTitle + "";

          var revid;

          revid = mergeHelper_editPageEx('talk:'+destTitle, destTalkPage, token, editSummary); // edit the destination Talk page

          document.getElementById('mergeHelper_finish').innerHTML += '

        • Done (Reload page)
        • ';

          //mergeHelper_movePage(mergeHelper_PageName, newtitle, token, 'Created via \[\[WP:AFC|Articles for Creation\]\] (\[\[WP:WPAFC|you can help!\]\])' , callback);

          }

          else if(action == 'accept'){

          var callback = function(){

          var merge_re = /\{\{\s*merge\s*(from|to)\s*\|(?:\{\{[^\{\}]*\}\}|[^\}\{])*\}\}/i;

          //sourceText.replace(merge_re, '');

          //destText.replace(merge_re, '');

          };

          sourceText = mergeHelper_getPageText(sourceTitle);

          destText = mergeHelper_getPageText(destTitle);

          destTalkText = mergeHelper_getPageText('talk:' +destTitle);

          var username ='';

          // clean up page

          var newSourceText = '#REDIRECT ' +destTitle +' {{R from merge}}';

          var newDestText = '{{Inuse}}\n\n' +destText + '\n\n\n' + sourceText;

          var sourceVarids;

          var destVarids;

          destVarids = mergeHelper_editPageEx(destTitle, newDestText, token, 'Merged content from ' +sourceTitle+ ' to here. See Talk:' +destTitle +'#Merger Proposal.');

          sourceVarids = mergeHelper_editPageEx(sourceTitle, newSourceText, token, 'Merged content to ' +destTitle + '. See Talk:' + destTitle + '#Merger Proposal.' );

          var diffUrl = mw.config.get('wgServer') + mw.config.get('wgScript') + "?title="+ encodeURI(destTitle) + "&action=historysubmit&diff=" + destVarids['edit']['newvarid'] + "&oldid=" +destVarids.oldvarid;

          var copiedTemplate = '{{Copied |from = ' + sourceTitle + '|from_oldid = ' +sourceVarids.oldvarid + '|to =' + destTitle +'|diff = ' +diffUrl +'|date=}}\n';

          var newDestTalkText = copiedTemplate + destTalkText;

          mergeHelper_editPage('talk:'+destTitle, newDestTalkText, token, 'Added Copied Template.' );

          } //end else if

          else if(action == 'decline' || action == 'hold'){

          var code = document.getElementById("mergeHelper_reason").value;

          var reasontext = mergeHelper_reasonhash[code];

          var customreason = document.getElementById("mergeHelper_comments").value;

          var append = false;

          var keep = false;

          var blank = document.getElementById("mergeHelper_blank").checked;

          var notify = document.getElementById("mergeHelper_notify").checked;

          jsMsg('

              ');

              document.getElementById('mergeHelper_finish').innerHTML += '

            • Done (Reload page)
            • ';

              var token = mergeHelper_getToken(true);

              var text = mergeHelper_getPageText(mergeHelper_PageName);

              // Find the first submission or onhold template on the page.

              var afc_re = /\{\{\s*afc submission\s*\|\s*[\||h|r](?:\{\{[^\{\}]*\}\}|[^\}\{])*\}\}/i;

              if( !afc_re.test( text ) ) {

              alert( "Unable to locate AFC submission template, aborting..." );

              return;

              }

              var afctemplate = afc_re.exec(text)[0];

              if(afctemplate.search(/\|\s*h\s*\|/i) != -1){

              if(action != 'decline'){

              append = confirm( "Submission is already on hold. Do you want to add your reason as a comment?" );

              if(!append){

              return;

              }

              }

              else

              if(code == 'reason' && customreason == ''){

              keep = true;

              }

              }

              if (!keep) {

              if(code == 'reason' && customreason == ''){

              alert("You must enter a reason!");

              return;

              }

              }

              var startindex = text.indexOf(afctemplate);

              var endindex = startindex + afctemplate.length;

              //data is always between the first pipe and the one before the timestamp.

              var firstpipe = afctemplate.indexOf('|');

              var endpipe = afctemplate.indexOf('|ts');

              var newtemplate = afctemplate.substring(0, firstpipe);

              var summary = '';

              var extra = '';

              var newcomment = '';

              if(code == 'cv'){

              extra = prompt("Please enter the url if available, starting with http://");

              }

              else if(code == 'dup'){

              extra = prompt("Please enter the title of the duplicate submission, if possible. Do not enter the prefix (e.g., John Doe).");

              }

              else if(code == 'mergeto'){

              extra = prompt("Please enter the title of the article to merge to, if possible.");

              }

              else if(code == 'exists'){

              extra = prompt("Please enter the title of the existing article, if possible.");

              }

              else if(code == 'plot'){

              extra = prompt("Please enter the title of the existing article on the fiction, if there is one.");

              }

              if(extra == null){

              return;

              }

              if(!keep && !append){

              // overwrite any reason that was there.

              newtemplate += '|';

              newtemplate += action.substring(0, 1);

              newtemplate += '|';

              newtemplate += code;

              if(code == 'reason'){

              newtemplate += '|3=';

              newtemplate += customreason;

              }

              else if(extra != ''){

              newtemplate += '|3=';

              newtemplate += extra;

              }

              newtemplate += afctemplate.substring(endpipe);

              if(code != 'reason' && customreason != ''){

              newcomment = "*\{\{afc comment|1=" + customreason + " \~\~\~\~\}\}";

              }

              summary = (action == 'decline' ? "Declining submission" : "Placing submission on hold");

              if(code == 'reason')

              summary += ': see comment therein';

              else

              summary += ': ' + reasontext;

              }

              else if (append){

              //append the reason as a comment.

              newtemplate = afctemplate;

              newcomment = "*\{\{afc comment|1=\{\{AFC submission/comments|";

              newcomment += code;

              if(code == 'reason'){

              newcomment += '|2=';

              newcomment += customreason;

              }

              else if(extra != ''){

              newcomment += '|2=';

              newcomment += extra;

              }

              newcomment += "\}\} \~\~\~\~ \}\}";

              summary = 'Comment on submission';

              if(code == 'reason')

              summary += '.';

              else

              summary += ': ' + reasontext;

              }

              else{

              // keep the original reason, just change hold to decline.

              var secondpipe = afctemplate.indexOf('|', firstpipe + 1);

              newtemplate += '|d';

              newtemplate += afctemplate.substring(secondpipe);

              summary = 'Decline submission for reasons stated in hold.';

              }

              if(!append && notify){

              var author_re = /\|\s*u=\s*[^\|]*\|/i;

              if(author_re.test(afctemplate)){

              var user = author_re.exec(afctemplate)[0];

              var username = user.split(/=/)[1];

              username = username.replace(/[\|]/g,'');

              var usertext = mergeHelper_getPageText("User talk:"+username);

              usertext += "\n== Your submission at \[\[WP:AFC|Articles for creation\]\] ==";

              if(action == 'decline'){

              usertext += "\n\{\{subst:afc decline|1=" + mergeHelper_submissionTitle;

              if(code == 'cv')

              usertext += "| cv = yes";

              usertext += "|sig=yes\}\}";

              }

              else

              usertext += "\n\{\{subst:afc onhold|1=" + mergeHelper_submissionTitle + "\}\} \~\~\~\~";

              mergeHelper_editPage("User talk:"+username, usertext, token, 'Your submission at \[\[WP:AFC|Articles for creation\]\]');

              }

              }

              if(!blank){

              var containComment = (text.indexOf('----') != -1);

              if(newcomment != ''){

              if(!containComment)

              text = text.substring(0, startindex) + newtemplate + '\n' + newcomment + '\n----\n'+ text.substring(endindex);

              else{

              text = text.substring(0, startindex) + newtemplate + text.substring(endindex);

              var idx = text.indexOf('----');

              text = text.substring(0, idx) + newcomment +'\n' + text.substring(idx);

              }

              }

              else

              text = text.substring(0, startindex) + newtemplate + text.substring(endindex);

              }

              else

              text = newtemplate + '\n' + newcomment + "\n\{\{afc cleared\}\}";

              if(action == 'decline'){

              // Comment out cats on decline.

              text = text.replace(/\[\[Category:/gi, "\[\[:Category:");

              }

              mergeHelper_editPage(mergeHelper_PageName, text, token, summary);

              }

              else if(action == 'comment'){

              var comment = document.getElementById("mergeHelper_comments").value;

              jsMsg('

                  ');

                  document.getElementById('mergeHelper_finish').innerHTML += '

                • Done (Reload page)
                • ';

                  var token = mergeHelper_getToken(true);

                  var text = mergeHelper_getPageText(mergeHelper_PageName);

                  var containComment = (text.indexOf('----') != -1);

                  var newComment = "*\{\{afc comment|1=" + comment + "\~\~\~\~\}\}";

                  if(comment != ''){

                  if(!containComment){

                  var afc_re = /\{\{\s*afc submission\s*\|\s*[\||h|r](?:\{\{[^\{\}]*\}\}|[^\}\{])*\}\}/i;

                  if( !afc_re.test( text ) ) {

                  alert( "Unable to locate AFC submission template, aborting..." );

                  return;

                  }

                  var afctemplate = afc_re.exec(text)[0];

                  var endindex = text.indexOf(afctemplate) + afctemplate.length;

                  text = text.substring(0, endindex) + '\n' + newComment + '\n----\n'+ text.substring(endindex);

                  }

                  else{

                  var idx = text.indexOf('----');

                  text = text.substring(0, idx) + newComment +'\n' + text.substring(idx);

                  }

                  mergeHelper_editPage(mergeHelper_PageName, text, token, "Commenting on submission");

                  }

                  }

                  else if(action == 'mark'){

                  jsMsg('

                      ');

                      document.getElementById('mergeHelper_finish').innerHTML += '

                    • Done (Reload page)
                    • ';

                      var token = mergeHelper_getToken(true);

                      var text = mergeHelper_getPageText(mergeHelper_PageName);

                      var afc_re = /\{\{\s*afc submission\s*\|\s*[\||h](?:\{\{[^\{\}]*\}\}|[^\}\{])*\}\}/i;

                      if( !afc_re.test( text ) ) {

                      alert( "Unable to locate AFC submission template, aborting..." );

                      return;

                      }

                      var afctemplate = afc_re.exec(text)[0];

                      var firstpipe = afctemplate.indexOf('|');

                      var endpipe = afctemplate.indexOf('|ts');

                      var newTemplate = afctemplate.substring(0, firstpipe);

                      newTemplate += '|r||';

                      newTemplate += afctemplate.substring(endpipe);

                      var startindex = text.indexOf(afctemplate);

                      var endindex = text.indexOf(afctemplate) + afctemplate.length;

                      text = text.substring(0, startindex) + newTemplate + text.substring(endindex);

                      mergeHelper_editPage(mergeHelper_PageName, text, token, "Marking submission as being reviewed");

                      }

                      document.getElementById('mergeHelper_finished_main').style.display = '';

                      }

                      function mergeHelper_getPageText(title) {

                      document.getElementById('mergeHelper_status').innerHTML += '

                    • Getting '+title+'
                    • ';

                      var req = sajax_init_object();

                      req.open("GET", wgScriptPath + "/api.php?action=query&prop=revisions&rvprop=content&format=json&indexpageids=1&titles="+encodeURIComponent(title), false);

                      req.send(null);

                      var response = eval('(' + req.responseText + ')');

                      pageid = response['query']['pageids'][0];

                      if (pageid == "-1") {

                      document.getElementById('mergeHelper_get'+escape(title)).innerHTML = ''+title+' does not exist';

                      delete req;

                      return '';

                      }

                      pagetext = response['query']['pages'][pageid]['revisions'][0]['*'];

                      delete req;

                      document.getElementById('mergeHelper_get'+escape(title)).innerHTML = 'Got '+title+'';

                      return pagetext;

                      }

                      function mergeHelper_getToken(show) {

                      if (show) {

                      document.getElementById('mergeHelper_status').innerHTML += '

                    • Getting token
                    • ';

                      }

                      var req = sajax_init_object();

                      req.open("GET", wgScriptPath + "/api.php?action=query&prop=info&indexpageids=1&intoken=edit&format=json&titles="+encodeURIComponent(mergeHelper_PageName), false);

                      req.send(null);

                      var response = eval('(' + req.responseText + ')');

                      pageid = response['query']['pageids'][0];

                      token = response['query']['pages'][pageid]['edittoken'];

                      delete req;

                      if (show) {

                      document.getElementById('mergeHelper_gettoken').innerHTML = 'Got token';

                      }

                      return token;

                      }

                      function mergeHelper_movePage(oldtitle, newtitle, token, summary, callback){

                      document.getElementById('mergeHelper_finished_wrapper').innerHTML = '';

                      var func_id = mergeHelper_AJAXnumber;

                      mergeHelper_AJAXnumber++;

                      document.getElementById('mergeHelper_status').innerHTML += '

                    • Moving '+oldtitle+' to '+newtitle+'
                    • ';

                      var req = sajax_init_object();

                      var params = "action=move&format=json&token="+encodeURIComponent(token)+"&from="+encodeURIComponent(oldtitle) +"&to="+encodeURIComponent(newtitle)+"&reason="+encodeURIComponent(summary);

                      url = wgScriptPath + "/api.php";

                      req.open("POST", url, true);

                      req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

                      req.setRequestHeader("Content-length", params.length);

                      req.setRequestHeader("Connection", "close");

                      req.onreadystatechange = function() {

                      if(req.readyState == 4 && req.status == 200) {

                      var error = true;

                      response = eval('(' + req.responseText + ')');

                      try {

                      if (typeof(response['move']) != "undefined") {

                      document.getElementById('mergeHelper_move'+escape(oldtitle)).innerHTML = 'Moved '+oldtitle+'';

                      error = false;

                      } else {

                      document.getElementById('mergeHelper_move'+escape(oldtitle)).innerHTML = '

                      Move failed on '+oldtitle+'
                      . Error info:' +response['error']['code'] + ' : ' + response['error']['info'];

                      }

                      }

                      catch(err) {

                      document.getElementById('mergeHelper_move'+escape(oldtitle)).innerHTML = '

                      Move failed on '+oldtitle+'
                      ';

                      }

                      if(!error){

                      if(callback != null)

                      callback();

                      }

                      document.getElementById('mergeHelper_AJAX_finished_'+func_id).style.display = '';

                      delete req;

                      }

                      };

                      req.send(params);

                      }

                      function mergeHelper_editPage(title, newtext, token, summary) {

                      document.getElementById('mergeHelper_finished_wrapper').innerHTML = '';

                      var func_id = mergeHelper_AJAXnumber;

                      mergeHelper_AJAXnumber++;

                      document.getElementById('mergeHelper_status').innerHTML += '

                    • Editing '+title+'
                    • ';

                      var req = sajax_init_object();

                      var params = "action=edit&format=json&token="+encodeURIComponent(token)+"&title="+encodeURIComponent(title)+"&text="+encodeURIComponent(newtext)+"¬minor=1&summary="+encodeURIComponent(summary);

                      url = wgScriptPath + "/api.php";

                      req.open("POST", url, true);

                      req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

                      req.setRequestHeader("Content-length", params.length);

                      req.setRequestHeader("Connection", "close");

                      req.onreadystatechange = function() {

                      if(req.readyState == 4 && req.status == 200) {

                      response = eval('(' + req.responseText + ')');

                      try {

                      if (response['edit']['result'] == "Success") {

                      document.getElementById('mergeHelper_edit'+escape(title)).innerHTML = 'Saved '+title+'';

                      } else {

                      document.getElementById('mergeHelper_edit'+escape(title)).innerHTML = '

                      Edit failed on '+title+'
                      . Error info:' +response['error']['code'] + ' : ' + response['error']['info'];

                      }

                      }

                      catch(err) {

                      document.getElementById('mergeHelper_edit'+escape(title)).innerHTML = '

                      Edit failed on '+title+'
                      ';

                      }

                      document.getElementById('mergeHelper_AJAX_finished_'+func_id).style.display = '';

                      delete req;

                      }

                      };

                      req.send(params);

                      }

                      function mergeHelper_editPageEx(title, newtext, token, summary ) {

                      var revid = {};

                      document.getElementById('mergeHelper_finished_wrapper').innerHTML = '';

                      var func_id = mergeHelper_AJAXnumber;

                      mergeHelper_AJAXnumber++;

                      document.getElementById('mergeHelper_status').innerHTML += '

                    • Editing '+title+'
                    • ';

                      var req = sajax_init_object();

                      var params = "action=edit&format=json&token="+encodeURIComponent(token)+"&title="+encodeURIComponent(title)+"&text="+encodeURIComponent(newtext)+"¬minor=1&summary="+encodeURIComponent(summary);

                      url = wgScriptPath + "/api.php";

                      req.open("POST", url, true);

                      req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

                      req.setRequestHeader("Content-length", params.length);

                      req.setRequestHeader("Connection", "close");

                      req.onreadystatechange = function() {

                      if(req.readyState == 4 && req.status == 200) {

                      response = eval('(' + req.responseText + ')');

                      try {

                      if (response['edit']['result'] == "Success") {

                      revid = {

                      'pageid' : response['edit']['pageid'],

                      'oldrevid' : response['edit']['oldrevid'],

                      'newrevid' : response['edit']['newrevid']

                      };

                      } else {

                      document.getElementById('mergeHelper_edit'+escape(title)).innerHTML = '

                      Edit failed on '+title+'
                      . Error info:' +response['error']['code'] + ' : ' + response['error']['info'];

                      }

                      }

                      catch(err) {

                      document.getElementById('mergeHelper_edit'+escape(title)).innerHTML = '

                      Edit failed on '+title+'
                      ';

                      }

                      document.getElementById('mergeHelper_AJAX_finished_'+func_id).style.display = '';

                      delete req;

                      }

                      };

                      req.send(params);

                      return response;

                      }

                      function mergeHelper_addLink() {

                      addPortletLink("p-cactions", "javascript:mergeHelper_init()", "MergeHelper", "ca-mergeHelper", "Article Merge Helper");

                      }

                      function mergeHelper_onChange(select){

                      var value = select.options[select.selectedIndex].value;

                      if(value == 'blp' || value == 'cv'){

                      document.getElementById("mergeHelper_blank").setAttribute("checked", "checked");

                      }

                      else

                      document.getElementById("mergeHelper_blank").removeAttribute("checked");

                      }

                      function mergeHelper_nowMonthYear(){

                      var today = new Date();

                      var monthnames = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");

                      month = monthnames[today.getUTCMonth()];

                      day = today.getUTCDate();

                      year = today.getUTCFullYear();

                      var datestring = month + " " + year;

                      return datestring;

                      }

                      function mergeHelper_generateSelect(title, options, onchange){

                      var text = '";

                      return text;

                      }

                      addOnloadHook(mergeHelper_addLink);

                      function values (k /*, and values */) {

                      return typeof k === "function"

                      ? k.apply(this, Array.prototype.slice.call(arguments, 1))

                      : arguments[1];

                      }

                      }

                      //