<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.endmyopia.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-twinklebatchundelete.js</id>
	<title>MediaWiki:Gadget-twinklebatchundelete.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.endmyopia.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-twinklebatchundelete.js"/>
	<link rel="alternate" type="text/html" href="https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-twinklebatchundelete.js&amp;action=history"/>
	<updated>2026-05-06T21:07:29Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-twinklebatchundelete.js&amp;diff=8583&amp;oldid=prev</id>
		<title>NottNott: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-twinklebatchundelete.js&amp;diff=8583&amp;oldid=prev"/>
		<updated>2020-06-12T10:46:06Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 10:46, 12 June 2020&lt;/td&gt;
				&lt;/tr&gt;
&lt;!-- diff cache key jakeendmy_mw1720-mwnr_:diff::1.12:old-8582:rev-8583 --&gt;
&lt;/table&gt;</summary>
		<author><name>NottNott</name></author>
	</entry>
	<entry>
		<id>https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-twinklebatchundelete.js&amp;diff=8582&amp;oldid=prev</id>
		<title>en&gt;Amorymeltzer: Repo at ffe5bbed: Use Morebits.date .calendar to format protection confirmations/notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-twinklebatchundelete.js&amp;diff=8582&amp;oldid=prev"/>
		<updated>2020-04-25T17:26:57Z</updated>

		<summary type="html">&lt;p&gt;Repo at ffe5bbed: Use Morebits.date .calendar to format protection confirmations/notes&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;// &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(function($) {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 ****************************************&lt;br /&gt;
 *** twinklebatchundelete.js: Batch undelete module&lt;br /&gt;
 ****************************************&lt;br /&gt;
 * Mode of invocation:     Tab (&amp;quot;Und-batch&amp;quot;)&lt;br /&gt;
 * Active on:              Existing user and project pages&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchundelete = function twinklebatchundelete() {&lt;br /&gt;
	if (!Morebits.userIsSysop || !mw.config.get('wgArticleId') || (&lt;br /&gt;
		mw.config.get('wgNamespaceNumber') !== mw.config.get('wgNamespaceIds').user &amp;amp;&amp;amp;&lt;br /&gt;
		mw.config.get('wgNamespaceNumber') !== mw.config.get('wgNamespaceIds').project)) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	Twinkle.addPortletLink(Twinkle.batchundelete.callback, 'Und-batch', 'tw-batch-undel', &amp;quot;Undelete 'em all&amp;quot;);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchundelete.callback = function twinklebatchundeleteCallback() {&lt;br /&gt;
	var Window = new Morebits.simpleWindow(600, 400);&lt;br /&gt;
	Window.setScriptName('Twinkle');&lt;br /&gt;
	Window.setTitle('Batch undelete');&lt;br /&gt;
	Window.addFooterLink('Twinkle help', 'WP:TW/DOC#batchundelete');&lt;br /&gt;
&lt;br /&gt;
	var form = new Morebits.quickForm(Twinkle.batchundelete.callback.evaluate);&lt;br /&gt;
	form.append({&lt;br /&gt;
		type: 'checkbox',&lt;br /&gt;
		list: [&lt;br /&gt;
			{&lt;br /&gt;
				label: 'Restore talk pages of undeleted pages if they existed',&lt;br /&gt;
				name: 'undel_talk',&lt;br /&gt;
				value: 'undel_talk',&lt;br /&gt;
				checked: true&lt;br /&gt;
			}&lt;br /&gt;
		]&lt;br /&gt;
	});&lt;br /&gt;
	form.append({&lt;br /&gt;
		type: 'input',&lt;br /&gt;
		name: 'reason',&lt;br /&gt;
		label: 'Reason: ',&lt;br /&gt;
		size: 60&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
	var statusdiv = document.createElement('div');&lt;br /&gt;
	statusdiv.style.padding = '15px';  // just so it doesn't look broken&lt;br /&gt;
	Window.setContent(statusdiv);&lt;br /&gt;
	Morebits.status.init(statusdiv);&lt;br /&gt;
	Window.display();&lt;br /&gt;
&lt;br /&gt;
	var query = {&lt;br /&gt;
		'action': 'query',&lt;br /&gt;
		'generator': 'links',&lt;br /&gt;
		'prop': 'info',&lt;br /&gt;
		'inprop': 'protection',&lt;br /&gt;
		'titles': mw.config.get('wgPageName'),&lt;br /&gt;
		'gpllimit': Twinkle.getPref('batchMax')&lt;br /&gt;
	};&lt;br /&gt;
	var statelem = new Morebits.status('Grabbing list of pages');&lt;br /&gt;
	var wikipedia_api = new Morebits.wiki.api('loading...', query, function(apiobj) {&lt;br /&gt;
		var xml = apiobj.responseXML;&lt;br /&gt;
		var $pages = $(xml).find('page[missing]');&lt;br /&gt;
		var list = [];&lt;br /&gt;
		$pages.each(function(index, page) {&lt;br /&gt;
			var $page = $(page);&lt;br /&gt;
			var title = $page.attr('title');&lt;br /&gt;
			var $editprot = $page.find('pr[type=&amp;quot;create&amp;quot;][level=&amp;quot;sysop&amp;quot;]');&lt;br /&gt;
			var isProtected = $editprot.length &amp;gt; 0;&lt;br /&gt;
&lt;br /&gt;
			list.push({&lt;br /&gt;
				label: title + (isProtected ? ' (fully create protected' +&lt;br /&gt;
					($editprot.attr('expiry') === 'infinity' ? ' indefinitely' : ', expires ' + new Morebits.date($editprot.attr('expiry')).calendar('utc') + ' (UTC)') + ')' : ''),&lt;br /&gt;
				value: title,&lt;br /&gt;
				checked: true,&lt;br /&gt;
				style: isProtected ? 'color:red' : ''&lt;br /&gt;
			});&lt;br /&gt;
		});&lt;br /&gt;
		apiobj.params.form.append({ type: 'header', label: 'Pages to undelete' });&lt;br /&gt;
		apiobj.params.form.append({&lt;br /&gt;
			type: 'button',&lt;br /&gt;
			label: 'Select All',&lt;br /&gt;
			event: function(e) {&lt;br /&gt;
				$(Morebits.quickForm.getElements(e.target.form, 'pages')).prop('checked', true);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		apiobj.params.form.append({&lt;br /&gt;
			type: 'button',&lt;br /&gt;
			label: 'Deselect All',&lt;br /&gt;
			event: function(e) {&lt;br /&gt;
				$(Morebits.quickForm.getElements(e.target.form, 'pages')).prop('checked', false);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		apiobj.params.form.append({&lt;br /&gt;
			type: 'checkbox',&lt;br /&gt;
			name: 'pages',&lt;br /&gt;
			list: list&lt;br /&gt;
		});&lt;br /&gt;
		apiobj.params.form.append({ type: 'submit' });&lt;br /&gt;
&lt;br /&gt;
		var result = apiobj.params.form.render();&lt;br /&gt;
		apiobj.params.Window.setContent(result);&lt;br /&gt;
&lt;br /&gt;
		Morebits.checkboxShiftClickSupport(Morebits.quickForm.getElements(result, 'pages'));&lt;br /&gt;
	}, statelem);&lt;br /&gt;
	wikipedia_api.params = { form: form, Window: Window };&lt;br /&gt;
	wikipedia_api.post();&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchundelete.callback.evaluate = function(event) {&lt;br /&gt;
	Morebits.wiki.actionCompleted.notice = 'Batch undeletion is now complete';&lt;br /&gt;
&lt;br /&gt;
	var numProtected = $(Morebits.quickForm.getElements(event.target, 'pages')).filter(function(index, element) {&lt;br /&gt;
		return element.checked &amp;amp;&amp;amp; element.nextElementSibling.style.color === 'red';&lt;br /&gt;
	}).length;&lt;br /&gt;
	if (numProtected &amp;gt; 0 &amp;amp;&amp;amp; !confirm('You are about to undelete ' + numProtected + ' fully create protected page(s). Are you sure?')) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	var pages = event.target.getChecked('pages');&lt;br /&gt;
	var reason = event.target.reason.value;&lt;br /&gt;
	var undel_talk = event.target.reason.value;&lt;br /&gt;
	if (!reason) {&lt;br /&gt;
		alert('You need to give a reason, you cabal crony!');&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	Morebits.simpleWindow.setButtonsEnabled(false);&lt;br /&gt;
	Morebits.status.init(event.target);&lt;br /&gt;
&lt;br /&gt;
	if (!pages) {&lt;br /&gt;
		Morebits.status.error('Error', 'nothing to undelete, aborting');&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	var pageUndeleter = new Morebits.batchOperation('Undeleting pages');&lt;br /&gt;
	pageUndeleter.setOption('chunkSize', Twinkle.getPref('batchUndeleteChunks'));&lt;br /&gt;
	pageUndeleter.setOption('preserveIndividualStatusLines', true);&lt;br /&gt;
	pageUndeleter.setPageList(pages);&lt;br /&gt;
	pageUndeleter.run(function(pageName) {&lt;br /&gt;
		var params = {&lt;br /&gt;
			page: pageName,&lt;br /&gt;
			undel_talk: undel_talk,&lt;br /&gt;
			reason: reason,&lt;br /&gt;
			pageUndeleter: pageUndeleter&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		var wikipedia_page = new Morebits.wiki.page(pageName, 'Undeleting page ' + pageName);&lt;br /&gt;
		wikipedia_page.setCallbackParameters(params);&lt;br /&gt;
		wikipedia_page.setEditSummary(reason + Twinkle.getPref('deletionSummaryAd'));&lt;br /&gt;
		wikipedia_page.suppressProtectWarning();&lt;br /&gt;
		wikipedia_page.setMaxRetries(3); // temporary increase from 2 to make batchundelete more likely to succeed [[phab:T222402]] #613&lt;br /&gt;
		wikipedia_page.undeletePage(Twinkle.batchundelete.callbacks.doExtras, pageUndeleter.workerFailure);&lt;br /&gt;
	});&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchundelete.callbacks = {&lt;br /&gt;
	// this stupid parameter name is a temporary thing until I implement an overhaul&lt;br /&gt;
	// of Morebits.wiki.* callback parameters&lt;br /&gt;
	doExtras: function(thingWithParameters) {&lt;br /&gt;
		var params = thingWithParameters.parent ? thingWithParameters.parent.getCallbackParameters() :&lt;br /&gt;
			thingWithParameters.getCallbackParameters();&lt;br /&gt;
		// the initial batch operation's job is to delete the page, and that has&lt;br /&gt;
		// succeeded by now&lt;br /&gt;
		params.pageUndeleter.workerSuccess(thingWithParameters);&lt;br /&gt;
&lt;br /&gt;
		var query, wikipedia_api;&lt;br /&gt;
&lt;br /&gt;
		if (params.undel_talk) {&lt;br /&gt;
			var talkpagename = new mw.Title(params.page).getTalkPage().getPrefixedText();&lt;br /&gt;
			if (talkpagename !== params.page) {&lt;br /&gt;
				query = {&lt;br /&gt;
					'action': 'query',&lt;br /&gt;
					'prop': 'deletedrevisions',&lt;br /&gt;
					'drvprop': 'ids',&lt;br /&gt;
					'drvlimit': 1,&lt;br /&gt;
					'titles': talkpagename&lt;br /&gt;
				};&lt;br /&gt;
				wikipedia_api = new Morebits.wiki.api('Checking talk page for deleted revisions', query, Twinkle.batchundelete.callbacks.undeleteTalk);&lt;br /&gt;
				wikipedia_api.params = params;&lt;br /&gt;
				wikipedia_api.params.talkPage = talkpagename;&lt;br /&gt;
				wikipedia_api.post();&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	undeleteTalk: function(apiobj) {&lt;br /&gt;
		var xml = apiobj.responseXML;&lt;br /&gt;
		var exists = $(xml).find('page:not([missing])').length &amp;gt; 0;&lt;br /&gt;
		var delrevs = $(xml).find('rev').attr('revid');&lt;br /&gt;
&lt;br /&gt;
		if (exists || !delrevs) {&lt;br /&gt;
			// page exists or has no deleted revisions; forget about it&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var page = new Morebits.wiki.page(apiobj.params.talkPage, 'Undeleting talk page of ' + apiobj.params.page);&lt;br /&gt;
		page.setEditSummary('Undeleting [[Help:Talk page|talk page]] of &amp;quot;' + apiobj.params.page + '&amp;quot;' + Twinkle.getPref('deletionSummaryAd'));&lt;br /&gt;
		page.undeletePage();&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
})(jQuery);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>en&gt;Amorymeltzer</name></author>
	</entry>
</feed>