미디어위키:Gadget-twinklearv.js

// ', {
									'class': 'entry'
								});
								var $input = $(, {
									'type': 'checkbox',
									'name': 's_' + field,
									'value': rev.revid
								});
								$input.data('revinfo', rev);
								$input.appendTo($entry);
								var comment = ;
								// revdel/os
								if (typeof rev.commenthidden === 'string') {
									comment += '(comment hidden)';
								} else {
									comment += '"' + rev.parsedcomment + '"';
								}
								comment += ' at ' + new Morebits.date(rev.timestamp).calendar() + ;
								$entry.append(comment).appendTo($field);
							}
							// add free form input for resolves
							if (field === 'resolves') {
								var $free_entry = $(, {
									'class': 'entry'
								});
								var $free_input = $(, {
									'type': 'text',
									'name': 's_resolves_free'
								});
								var $free_label = $(, {
									'for': 's_resolves_free',
									'html': 'URL link of diff with additional discussions: '
								});
								$free_entry.append($free_label).append($free_input).appendTo($field);
							}
						}).fail(function() {
							$('API failure, reload page and try again').appendTo($field);
						});
					};
					// warnings
					var uid = root.uid.value;
					getAN3Entries('warnings', mw.config.get('wgUserName'), 'User talk:' + uid);
					// diffs and resolves require a valid page
					var page = root.page.value;
					if (page) {
						// diffs
						getAN3Entries('diffs', uid, page);
						// resolutions
						var t = new mw.Title(page);
						var talk_page = t.getTalkPage().getPrefixedText();
						getAN3Entries('resolves', mw.config.get('wgUserName'), talk_page);
					} else {
						$(root).find('name=diffs').find('.entry').remove();
						$(root).find('name=resolves').find('.entry').remove();
					}
				}
			});
			work_area.append({
				type: 'field',
				name: 'diffs',
				label: 'User\'s reverts',
				tooltip: 'Select the edits you believe are reverts'
			});
			work_area.append({
				type: 'field',
				name: 'warnings',
				label: 'Warnings given to subject',
				tooltip: 'You must have warned the subject before reporting'
			});
			work_area.append({
				type: 'field',
				name: 'resolves',
				label: 'Resolution initiatives',
				tooltip: 'You should have tried to resolve the issue on the talk page first'
			});
			work_area.append({
				type: 'textarea',
				label: 'Comment:',
				name: 'comment'
			});
			work_area = work_area.render();
			old_area.parentNode.replaceChild(work_area, old_area);
			break;
	}
};
Twinkle.arv.callback.evaluate = function(e) {
	var form = e.target;
	var reason = ;
	var comment = ;
	if (form.reason) {
		comment = form.reason.value;
	}
	var uid = form.uid.value;
	var types;
	switch (form.category.value) {
		// Report user for vandalism
		case 'aiv':
			/* falls through */
		default:
			types = form.getChecked('arvtype');
			if (!types.length && comment === ) {
				alert('You must specify some reason');
				return;
			}
			types = types.map(function(v) {
				switch (v) {
					case 'final':
						return 'vandalism after final warning';
					case 'postblock':
						return 'vandalism after recent release of block';
					case 'vandalonly':
						return 'actions evidently indicate a vandalism-only account';
					case 'promoonly':
						return 'account is being used only for promotional purposes';
					case 'spambot':
						return 'account is evidently a spambot or a compromised account';
					default:
						return 'unknown reason';
				}
			}).join('; ');
			if (form.page.value !== ) {
				// Allow links to redirects, files, and categories
				reason = 'On :' + form.page.value + ;
				if (form.badid.value !== ) {
					reason += ' (diff)';
				}
				reason += ':';
			}
			if (types) {
				reason += ' ' + types;
			}
			if (comment !== ) {
				reason += (reason ===  ?  : '. ') + comment;
			}
			reason = reason.trim();
			if (!/.?!;$/.test(reason)) {
				reason += '.';
			}
			reason += ' ~~~~';
			reason = reason.replace(/\r?\n/g, '\n*:');  // indent newlines
			Morebits.simpleWindow.setButtonsEnabled(false);
			Morebits.status.init(form);
			Morebits.wiki.actionCompleted.redirect = 'Wikipedia:Administrator intervention against vandalism';
			Morebits.wiki.actionCompleted.notice = 'Reporting complete';
			var aivPage = new Morebits.wiki.page('Wikipedia:Administrator intervention against vandalism', 'Processing AIV request');
			aivPage.setPageSection(1);
			aivPage.setFollowRedirect(true);
			aivPage.load(function() {
				var text = aivPage.getPageText();
				var $aivLink = 'WP:AIV';
				// check if user has already been reported
				if (new RegExp('\\{\\{\\s*(?:(?:IiPp)?Vvandal|Uuserlinks)\\s*\\|\\s*(?:1=)?\\s*' + RegExp.escape(uid, true) + '\\s*\\}\\}').test(text)) {
					aivPage.getStatusElement().error('Report already present, will not add a new one');
					Morebits.status.printUserText(reason, 'The comments you typed are provided below, in case you wish to manually post them under the existing report for this user at ' + $aivLink + ':');
					return;
				}
				// then check for any bot reports
				var tb2Page = new Morebits.wiki.page('Wikipedia:Administrator intervention against vandalism/TB2', 'Checking bot reports');
				tb2Page.load(function() {
					var tb2Text = tb2Page.getPageText();
					var tb2statelem = tb2Page.getStatusElement();
					if (new RegExp('\\{\\{\\s*(?:(?:IiPp)?Vvandal|Uuserlinks)\\s*\\|\\s*(?:1=)?\\s*' + RegExp.escape(uid, true) + '\\s*\\}\\}').test(tb2Text)) {
						if (confirm('The user ' + uid + ' has already been reported by a bot. Do you wish to make the report anyway?')) {
							tb2statelem.info('Proceeded despite bot report');
						} else {
							tb2statelem.error('Report from a bot is already present, stopping');
							Morebits.status.printUserText(reason, 'The comments you typed are provided below, in case you wish to manually post them at ' + $aivLink + ':');
							return;
						}
					} else {
						tb2statelem.info('No conflicting bot reports');
					}
					aivPage.getStatusElement().status('Adding new report...');
					aivPage.setEditSummary('Reporting ' + uid + '.' + Twinkle.getPref('summaryAd'));
					aivPage.setAppendText('\n*' + (/=/.test(uid) ? '1=' : ) + uid + ' – ' + reason);
					aivPage.append();
				});
			});
			break;
		// Report inappropriate username
		case 'username':
			types = form.getChecked('arvtype').map(Morebits.string.toLowerCaseFirstChar);
			var hasShared = types.indexOf('shared') > -1;
			if (hasShared) {
				types.splice(types.indexOf('shared'), 1);
			}
			if (types.length WP:UAA';
					Morebits.status.printUserText(reason, 'The comments you typed are provided below, in case you wish to manually post them under the existing report for this user at ' + $uaaLink + ':');
					return;
				}
				uaaPage.getStatusElement().status('Adding new report...');
				uaaPage.setEditSummary('Reporting ' + uid + '.' + Twinkle.getPref('summaryAd'));
				uaaPage.setPageText(text + '\n' + reason);
				uaaPage.save();
			});
			break;
		// WP:SPI
		case 'sock':
			/* falls through */
		case 'puppet':
			var sockParameters = {
				evidence: form.evidence.value.trim(),
				checkuser: form.checkuser.checked,
				notify: form.notify.checked
			};
			var puppetReport = form.category.value === 'puppet';
			if (puppetReport && !form.sockmaster.value.trim()) {
				alert('You have not entered a sockmaster account for this puppet. Consider reporting this account as a sockpuppeteer instead.');
				return;
			} else if (!puppetReport && !form.sockpuppet0.value.trim()) {
				alert('You have not entered any sockpuppet account(s) for this sockmaster. Consider reporting this account as a sockpuppet instead.');
				return;
			}
			sockParameters.uid = puppetReport ? form.sockmaster.value.trim() : uid;
			sockParameters.sockpuppets = puppetReport ? uid : $.map($('input:textname=sockpuppet', form), function(o) {
				return $(o).val() 
null;
			});
			Morebits.simpleWindow.setButtonsEnabled(false);
			Morebits.status.init(form);
			Twinkle.arv.processSock(sockParameters);
			break;
		case 'an3':
			var diffs = $.map($('input:checkboxname=s_diffs:checked', form), function(o) {
				return $(o).data('revinfo');
			});
			if (diffs.length  0) {
		var notifyEditSummary = 'Notifying about suspicion of sockpuppeteering.' + Twinkle.getPref('summaryAd');
		var notifyText = '\n\n1=' + params.uid + ' ~~~~';
		// notify user's master account
		var masterTalkPage = new Morebits.wiki.page('User talk:' + params.uid, 'Notifying suspected sockpuppeteer');
		masterTalkPage.setFollowRedirect(true);
		masterTalkPage.setEditSummary(notifyEditSummary);
		masterTalkPage.setAppendText(notifyText);
		masterTalkPage.append();
		var statusIndicator = new Morebits.status('Notifying suspected sockpuppets', '0%');
		var total = params.sockpuppets.length;
		var current = 0;
		// display status of notifications as they progress
		var onSuccess = function(sockTalkPage) {
			var now = parseInt(100 * ++current / total, 10) + '%';
			statusIndicator.update(now);
			sockTalkPage.getStatusElement().unlink();
			if (current >= total) {
				statusIndicator.info(now + ' (completed)');
			}
		};
		var socks = params.sockpuppets;
		// notify each puppet account
		for (var i = 0; i = 2) {
				var last = sub0;
				var first = sub.slice(-1)0;
				var label = 'Consecutive edits made from ' + new Morebits.date(first.timestamp).format('HH:mm, D MMMM YYYY', 'utc') + ' (UTC) to ' + new Morebits.date(last.timestamp).format('HH:mm, D MMMM YYYY', 'utc') + ' (UTC)';
				ret = '# label=' + label + '\n';
			}
			ret += sub.reverse().map(function(v) {
				return (sub.length >= 2 ? '#' : ) + '# ' + new Morebits.date(v.timestamp).format('HH:mm, D MMMM YYYY', 'utc') + ' (UTC) ' + hasHiddenComment(v);
			}).join('\n');
			return ret;
		}).reverse().join('\n');
		var warningtext = params.warnings.reverse().map(function(v) {
			return '# ' + ' ' + new Morebits.date(v.timestamp).format('HH:mm, D MMMM YYYY', 'utc') + ' (UTC) ' + hasHiddenComment(v);
		}).join('\n');
		var resolvetext = params.resolves.reverse().map(function(v) {
			return '# ' + ' ' + new Morebits.date(v.timestamp).format('HH:mm, D MMMM YYYY', 'utc') + ' (UTC) ' + hasHiddenComment(v);
		}).join('\n');
		if (params.free_resolves) {
			var page = params.free_resolves;
			if (page.compare) {
				resolvetext += '\n# ' + ' label=Consecutive edits on ' + page.compare.totitle + ;
			} else if (page.revisions) {
				var revCount = page.revisions.length;
				var rev;
				if (revCount