MediaWiki:Gadget-UndelReq.js

From wikishia

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
 Description: Support for quick closing undeletion requests at Commons.
* @Authors: 
	(previous closeudel.js, closecfd.js - by [[User:King of Hearts]])
	Rewritten in 05-2015 by [[User:Perhelion]]
	 - derived from [[MediaWiki:Gadget-DelReqHandler.js]]
		- by [[User:Lupo]], 10-2007 - 01-2008
		- and [[User:DieBuche]], 02-2011
* @License: Quadruple licensed GFDL, GPL, LGPL and Creative Commons Attribution 3.0 (CC-BY-3.0)
	Choose whichever license of these you like best :-)
* @Revision: 01:34, 12 January 2016 (UTC)
* required modules: user.options
<nowiki>
**/
/*global mediaWiki, jQuery*/
/*jshint curly:false, smarttabs:true */

(function ($, mw) {
'use strict';

//Guard against double inclusions //Enable the whole shebang only for sysops.
if ('object' === typeof unDelReq || $.inArray('sysop', mw.config.get('wgUserGroups')) === -1) return;

var unDelReq = window.unDelReq = {
	/*------------------------------------------------------------------------------------------
	Undeletion request closing: add "[done]" and "[not done]" links to the left of the section edit
	links of a deletion request. [done] and [not done] prompt for an (optional) reason, then
	add "udelh" and "udelf" plus the reason and signature (four tildes).
	------------------------------------------------------------------------------------------*/
	setup : function () {
		var $content = [];
		var ti = mw.config.get('wgTitle');
		var DRV = /^Undeletion requests(\/Current requests)?$/.test(ti);
		var CFD = (DRV)? false : /^Categories for discussion\/20\d\d[^\s]*/.test(ti);
		if (DRV && mw.config.get('wgAction') === 'edit') {
    		$('#UdelReqHandlerAdminNote').hide();
    	}
		if ((DRV || CFD) && mw.config.get('wgAction') === 'view' && document.URL.search(/[?&]oldid=/) === -1)
			// We're on COM:UNDEL or one of its subpages
			// Don't do anything if we're not viewing the current version of the page
			$content = $('#bodyContent, #mw_contentholder');
		if (!$content.length) return;
		//mw.util.addCSS('.reqHandlerLinks {font-size: 85%;}');
		var hl = 'h2',	// headline
			hc = '.delh',	// headline class
			linkRegex = /Commons:Undeletion_requests\/Current_requests&[^\s]+/;
		this.th = 'udelh';	// template header
		this.tf = 'udelf';	// template footer
		if (CFD) {
			hl = 'h3';
			hc = '.cfdh';
			linkRegex = /Commons:Categories_for_discussion\/20\d\d\/\d\d\/[^\s]*?&section=(T-)?[12]$/;
			this.th = 'cfdh';
			this.tf = 'cfdf';
		}
		$content.find(hl).each(function () {
				var $t = $(this),
					unclosed = ($t.parents(hc).length < 1),
					discussion = $t.nextUntil(hl + ", .printfooter," + hc).add($t), // using for fakeReload
					editLink = $t.find('span.mw-editsection').not('.mw-editsection-visualeditor').eq(0),
					requestHref = editLink.find('a').eq(0).attr('href');
	//console.log(requestHref,linkRegex.test(requestHref),unclosed)
				if (!linkRegex.test(requestHref) || !unclosed) return true;
				// It's really an edit lk to a request subpage, and not a section
				unDelReq.addLinks(requestHref, editLink, discussion);
			});
	},
	titleFromHref : function (href) {
		if (href) {
			if (mw.util.getParamValue('title', href))
				return mw.util.getParamValue('title', href).replace(/_/g, ' ');
			var prefix = mw.config.get('wgArticlePath').replace('$1', "");
			// Fully expanded URL?
			if (href.indexOf(prefix) !== 0)
				prefix = mw.config.get('wgServer') + prefix;
			if (href.indexOf(prefix) !== 0 && prefix.indexOf('//') === 0)
				prefix = document.location.protocol + prefix; // protocol-relative wgServer?
			if (href.indexOf(prefix) === 0)
				return decodeURIComponent(href.substring(prefix.length)).replace(/_/g, ' ');
		}
		return "";
	},
	addLinks : function (requestHref, editLink, discussion) {
		function click (e) {
			e.preventDefault();
			e = (e.target.name)? "not " : ""; // Use link.name for decision boolean
			unDelReq.process(e + "done", requestHref, [editLink, span, discussion]);
		}
		var linkK = $('<a/>', { href: '#', text: 'not', name: 1, click: click }),
			linkU = $('<a/>', { href: '#', text: 'done', click: click }),
			span = $('<span/>', { 'class': 'navbar' });
		span.append(' [').append(linkK).append('] [').append(linkU).append(']');
		editLink.after(span);
	},
	process : function (decision, requestHref, domElements) {
		//Merge the page processing functions into our new process
		$.extend(this, unDelReq.processHelpers);
		this.tasks = [];
		this.requestPage = unDelReq.titleFromHref(requestHref).replace(/_/g, ' ');
		this.section = mw.util.getParamValue('section', requestHref).replace(/T-/g, '');
		this.decision = decision;
		this.domElements = domElements;
		this.addTask('getPages');
		this.reason = $.trim(prompt("Closing rationale?"));
		if (!this.reason) return; // User canceled
		this.addTask('closeRequest');
		this.addTask('fakeReload');
		this.nextTask();
	}
};
unDelReq.processHelpers = {
	getPages : function () {
		var url = mw.config.get('wgServer') + mw.config.get('wgScript'),
			query = {
			action : 'raw',
			section : this.section,
			title : this.requestPage
		};
		this.doAPICall(query, 'nextTask', url);
	},
	closeRequest : function () {
		var text = this.text;
		if (!text) return alert("No text!?");
		var tmp = '{{'+this.th+'}}';
		var ltmp = text.lastIndexOf(tmp); // remove last udelh of possible following thread
		// Add dashes on 'lesser' individual signatures
		var uSig = (mw.user.options.get('fancysig') && mw.user.options.get('nickname').search(/^[ ']*\[\[/) !== 0)?
			'' : '--';
		if (ltmp !== -1) {
			text = text.slice(0, ltmp);
			ltmp = '\n' + tmp;
		} else
			ltmp = "";
		this.reason = this.reason.replace(/[.\s-]*$/, '. ');
		text = tmp + '\n' + $.trim(text) + '\n----\n{{' + this.decision + '}}: ' + this.reason + uSig +'~~' + '~~\n{{'+ this.tf +'}}'+ ltmp;
		var page = {
			title : this.requestPage,
			text : text,
			section : this.section,
			summary : "/* " + this.domElements[2].find('span.mw-headline').eq(0).attr('id').replace(/_/g, ' ') + " */ closing request as " + this.decision,
			editType : 'text'
		};
		this.savePage(page, 'nextTask');
	},
	fakeReload : function () {
		var dE = this.domElements;
		//Remove links
		dE[1].remove();
		dE[2].eq(0).before('<i>This undeletion debate is now closed. Please do not make any edits to this archive.</i>');
		dE[2].eq(-1).after('<br><span style="color:green">Saved successfully.<br>This is just an approximate rendering. Reload to see the actual request.</span>');
		dE[2].eq(-1).after('<b>' + this.decision + '</b> ' + this.reason + ' --' + mw.config.get('wgUserName'));
		dE[2].eq(-1).after('<hr>');
		dE[2].wrapAll('<div class="delh">');
	},
	/**
	 ** Simple task queue.  addTask() adds a new task to the queue, nextTask() executes
	 ** the next scheduled task.  Tasks are specified as method names to call.
	 **/
	// list of pending tasks
	currentTask : '',
	// current task, for error reporting
	addTask : function (task) {
		this.tasks.push(task);
	},
	nextTask : function () {
		var task = this.currentTask = this.tasks.shift();
		if (task)
			try {
				this[task]();
			} catch (e) {
				this.fail(e);
			}
	},
	savePage : function (page, callback) {
		page.action = 'edit';
		page.format = 'json';
		page.token = mw.user.tokens.get('csrfToken');
		this.doAPICall(page, callback, mw.util.wikiScript('api'));
	},
	fail : function (e) {
		alert(e);
	},
	doAPICall : function (params, callback, url) {
		var k = this;
		//params.format = 'json';
		$.ajax({
			url : url,
			//dataType: 'json',
			data : params,
			type : 'POST',
			success : function (result, status, x) {
				if (!result)
					return k.fail("Receive empty API response:\n" + x.responseText);
				// In case we get the mysterious 231 unknown error, just try again
				if (result.error && result.error.info.indexOf('231') !== -1)
					return setTimeout(function () {
						k.doAPICall(params, callback);
					}, 500);
				if (result.error)
					return k.fail("API request failed (" + result.error.code + "): " + result.error.info);
				k.text = result;
				k[callback](result);
			},
			error : function (x, status, error) {
				return k.fail("API request returned code " + x.status + " " + status + "Error code is " + error);
			}
		});
	},
};

mw.loader.using('user.options', function () {
	if (mw.config.get('wgNamespaceNumber') === 4) $(unDelReq.setup());
});
})(jQuery, mediaWiki);