MediaWiki:Gadget-PatrollingEnhancements.js: difference between revisions

From Wiktionary, the free dictionary
Jump to navigation Jump to search
Content deleted Content added
if patrolling or deletion fails, and data.error.code is 'badtoken', then include token in alert-message
→‎Patrol-buttons: if we don't get a token, don't buttonify
Line 175: Line 175:
{
{
var token = data.query.recentchanges[0].patroltoken;
var token = data.query.recentchanges[0].patroltoken;
if(! token || token.search(/^[0-9a-f]{32}\+\\$/) != 0)
return;
var links =
var links =
document.getElementById('bodyContent').getElementsByTagName('a');
document.getElementById('bodyContent').getElementsByTagName('a');
Line 191: Line 193:


/* </pre>
/* </pre>

==Delete-buttons==
==Delete-buttons==
<pre> */
<pre> */

Revision as of 13:05, 23 April 2012

var GPE = new Object();

/* </pre>
==Configuration options==
<pre> */

// The initial value to put in the "deletion reason" text-field; you can
// override this in your common.js (or vector.js or whatnot).
GPE.initialDeleteReason = '';

// The value to use as a deletion reason if you leave the text-field blank; you
// can override it in your common.js (or vector.js or whatnot). If you *don't*
// override this, then MediaWiki will generate an automatic deletion reason that
// indicates the entry's last editor and the beginning of its content.
GPE.deleteReasonIfBlank = '';

// By DCDuring's request. If you set this to true, then Special:Watchlist will
// show the deletion-reason text-input, but *not* the deletion-reason dropdown,
// when there's an unpatrolled new-page-creation.
GPE.hideDeleteReasonDropdownOnWatchlist = false;

/* </pre>
==Automated patrolling (whitelisting)==
<pre> */

GPE.individualWhiteListedPages =
{
  "Wiktionary:Requests for verification": true,
  "Wiktionary:Requests for deletion": true,
  "Wiktionary:Requests for cleanup": true,
  "Wiktionary:Tea room": true,
  "Wiktionary:Beer parlour": true,
  "Wiktionary:Grease pit": true,
  "Wiktionary:Requested entries (English)": true,
  "Wiktionary:Requested entries (Spanish)": true,
  "Wiktionary:List of protologisms": true,
  "Wiktionary:Translation requests": true,
  "Wiktionary:Featured word candidates": true,
  "Wiktionary:Feedback": true,
  "Wiktionary:Information desk": true,
  "Wiktionary:Sandbox": true,
  "Wiktionary:Tutorial (Editing)/sandbox": true,
  "Wiktionary talk:Sandbox": true,
  "Wiktionary:Word of the day/Nominations": true
};

GPE.individualWhiteListedContributors =
{
  "16@r": true
};

GPE.shouldAutoPatrol = function(link)
{
  var pagename = link.title;
  if(pagename.indexOf('User talk:') == 0)
    return true;
  if(pagename in GPE.individualWhiteListedPages)
    return true;

  var contributor;
  {
    var links = link.parentNode.getElementsByTagName('a');
    for(var i = 0; i < links.length; ++i)
      if(links[i].title.indexOf('Special:Contributions/') == 0)
      {
        contributor = links[i].title.substr('Special:Contributions/'.length);
        break;
      }
  }
  if(pagename == 'User:' + contributor)
    return true;
  if(pagename == 'User:' + contributor + '/Sandbox')
    return true;
  if(contributor in GPE.individualWhiteListedContributors)
    return true;

  return false;
};

/* </pre>
==Utility functions==
<pre> */

GPE.newButton = function(text, color, hoverText)
{
  var button = newNode('button', text);
  button.style.background = color;
  button.style.color = '#FFF';
  button.style.border = '0';
  button.style.padding = '0';
  button.style.cursor = 'pointer';
  button.title = hoverText;
  return button;
};

GPE.disableButton = function(button, text, hoverText)
{
  button.onclick = null;
  button.title = (hoverText ? hoverText : '');
  button.innerHTML = text;
  // clear out explicit styling and disable, so we can get appropriate
  // disabled-button styles:
  button.style.background = '';
  button.style.color = '';
  button.style.cursor = '';
  button.disabled = 'disabled';
  // explicitly style like a disabled button:
  var computedStyle = window.getComputedStyle(button);
  button.style.background = computedStyle.backgroundColor;
  button.style.color = computedStyle.color;
  button.style.cursor = computedStyle.cursor;
  // re-enable, so the title will show up as hover-text in Firefox
  // (see https://bugzilla.mozilla.org/show_bug.cgi?id=274626):
  button.disabled = '';
  // technically the button is "enabled" now, but it *looks* disabled, and it
  // doesn't have an onclick event, so it's disabled for all normal purposes
};

/* </pre>
==Patrol-buttons==
<pre> */

GPE.addPatrolButton = function(link, rcid, token)
{
  var button = GPE.newButton('M', '#009', 'click to mark as patrolled');
  link.parentNode.insertBefore(button, link.nextSibling);
  link.parentNode.insertBefore(document.createTextNode(' · '), button);
  button.onclick =
    function ()
    {
      $.post
      (
        '/w/api.php?format=json&action=patrol',
        { token: token, rcid: rcid },
        function (data)
        {
          if(data.patrol)
            GPE.disableButton(button, 'm', 'marked as patrolled');
          else if(data.error)
          {
            var msg = data.error.code + ': ' + data.error.info;
            if(data.error.code == 'badtoken')
              msg += ': "' + token + '"';
            alert(msg);
          }
        },
        'json'
      );
    };
  if(GPE.shouldAutoPatrol(link))
    button.click();

  // remove the exclamation points:
  var abbreviations = link.parentNode.getElementsByTagName('abbr');
  for(var i = abbreviations.length - 1; i >= 0; --i)
    if((' '+abbreviations[i].className+' ').indexOf(' unpatrolled ') > -1)
      abbreviations[i].parentNode.removeChild(abbreviations[i]);
};


addOnloadHook
(
  function ()
  {
    if(mediaWiki.config.get('wgPageName') != 'Special:RecentChanges')
      if(mediaWiki.config.get('wgPageName') != 'Special:NewPages')
        if(mediaWiki.config.get('wgPageName') != 'Special:Watchlist')
          if(mediaWiki.config.get('wgAction') != 'markpatrolled')
            if(mediaWiki.config.get('wgAction') != 'delete')
              return;
    $.getJSON
    (
      '/w/api.php?format=json&action=query&list=recentchanges&rctoken=patrol',
      function (data)
      {
        var token = data.query.recentchanges[0].patroltoken;
        if(! token || token.search(/^[0-9a-f]{32}\+\\$/) != 0)
          return;
        var links =
          document.getElementById('bodyContent').getElementsByTagName('a');
        for(var i = links.length - 1; i >= 0; --i)
        {
          var link = links[i];
          if(link.href.search(/&rcid=\d+/) == -1)
            continue;
          var rcid = /&rcid=(\d+)/.exec(link.href)[1];
          GPE.addPatrolButton(link, rcid, token);
        }
      }
    );
  }
);

/* </pre>

==Delete-buttons==
<pre> */

GPE.addDeleteButton = function(link, title, token)
{
  var button = GPE.newButton('D', '#900', 'click to delete');
  link.parentNode.insertBefore(button, link.nextSibling);
  link.parentNode.insertBefore(document.createTextNode(' · '), button);
  button.onclick =
    function ()
    {
      var dropdownReason =
        document.getElementById('deleteReasonsDropdown')
          ? document.getElementById('deleteReasonsDropdown').value
          : '';
      if(dropdownReason == 'other')
        dropdownReason = '';
      var textInputReason =
        document.getElementById('deleteReasonTextInput').value;
      var reason;
      if(dropdownReason.length && textInputReason.length)
        reason = dropdownReason + ': ' + textInputReason;
      else if(dropdownReason.length || textInputReason.length)
        reason = dropdownReason + textInputReason;
      else
        reason = GPE.deleteReasonIfBlank;
      $.post
      (
        '/w/api.php?format=json&action=delete',
        { title: title, token: token, reason: reason },
        function (data)
        {
          if(data['delete'])
            GPE.disableButton(button, 'd', 'deleted');
          else if(data.error)
          {
            var msg = data.error.code + ': ' + data.error.info;
            if(data.error.code == 'badtoken')
              msg += ': "' + token + '"';
            alert(msg);
          }
        },
        'json'
      );
    };
};

GPE.addDeleteReasonInput = function()
{ var deleteReasonDiv =
    ( newNode
      ( 'div',
        { style:
            'background:#900; color:#FFF; ' +
            'position:fixed; bottom:0; right:0; margin-bottom:0'
        },
        '\u00A0Deletion reason:\u00A0'
      )
    );
  deleteReasonDiv.title =
    'the deletion reason (message/summary) to use when you click "D"';
  var deleteReasonTextInput =
  ( newNode
    ( 'input',
      { type: 'text',
        size: 80,
        id: 'deleteReasonTextInput',
        value: GPE.initialDeleteReason,
        style: 'position:fixed; right:0; margin-bottom:0'
      }
    )
  );
  deleteReasonDiv.appendChild(deleteReasonTextInput);
  document.getElementById('bodyContent').appendChild(deleteReasonDiv);

  if(GPE.hideDeleteReasonDropdownOnWatchlist)
    if(mediaWiki.config.get('wgPageName') == 'Special:Watchlist')
      return;

  // get canned messages from [[MediaWiki:Deletereason-dropdown]] (page #840741):
  $.getJSON
  ( '/w/api.php?format=json&action=query&prop=revisions&pageids=840741&rvprop=content',
    function (data)
    { var rawDeleteReasons = data.query.pages['840741'].revisions[0]['*'];
      var deleteReasonsDropdown =
        newNode('select',
          { id: 'deleteReasonsDropdown', style: 'vertical-align: bottom' });
      deleteReasonsDropdown.appendChild
        (newNode('option', { value: 'other' }, 'Other reason'));
      var optGroup = deleteReasonsDropdown;
      rawDeleteReasons.replace
      ( /^(\*\*?) *(.+)$/gm,
        function (s, asterisks, text)
        { if(asterisks == '*')
            deleteReasonsDropdown.appendChild
              (optGroup = newNode('optgroup', { label: text }));
          else // '**'
            optGroup.appendChild(newNode('option', { value: text }, text));
        }
      );
      deleteReasonDiv.insertBefore(deleteReasonsDropdown, deleteReasonTextInput);
      deleteReasonDiv.insertBefore(newNode('br'), deleteReasonTextInput);
      deleteReasonDiv.insertBefore(document.createTextNode('\u00A0'), deleteReasonTextInput);
    }
  );
};

addOnloadHook
( function ()
  {
    if(mediaWiki.config.get('wgPageName') != 'Special:RecentChanges')
      if(mediaWiki.config.get('wgPageName') != 'Special:NewPages')
        if(mediaWiki.config.get('wgPageName') != 'Special:Watchlist')
          if(mediaWiki.config.get('wgAction') != 'markpatrolled')
            if(mediaWiki.config.get('wgAction') != 'delete')
              return;
    $.getJSON
    (
      '/w/api.php?format=json&action=query&prop=info&titles=:&intoken=delete',
      function (data)
      {
        var token = data.query.pages['-1'].deletetoken;
        var links =
          document.getElementById('bodyContent').getElementsByTagName('a');
        var shouldAddDeleteReasonInput = false;
        for(var i = links.length - 1; i >= 0; --i)
        {
          var link = links[i];
          if(link.href.search(/#/) == -1) // skip within-page links (don't ask . . .)
            if(link.href.search(/&rcid=\d+/) > -1) // only want patrolled edits
              if(link.href.search(/&diff=\d+/) == -1) // only want new pages
              {
                GPE.addDeleteButton(link, link.title, token);
                shouldAddDeleteReasonInput = true;
              }
        }
        if(shouldAddDeleteReasonInput)
          GPE.addDeleteReasonInput();
      }
    );
  }
);