<?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-twinklebatchdelete.js</id>
	<title>MediaWiki:Gadget-twinklebatchdelete.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-twinklebatchdelete.js"/>
	<link rel="alternate" type="text/html" href="https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-twinklebatchdelete.js&amp;action=history"/>
	<updated>2026-09-17T07:47:08Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-twinklebatchdelete.js&amp;diff=8599&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-twinklebatchdelete.js&amp;diff=8599&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;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key jakeendmy_mw1720-mwnr_:diff:1.41:old-8598:rev-8599 --&gt;
&lt;/table&gt;</summary>
		<author><name>NottNott</name></author>
	</entry>
	<entry>
		<id>https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-twinklebatchdelete.js&amp;diff=8598&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-twinklebatchdelete.js&amp;diff=8598&amp;oldid=prev"/>
		<updated>2020-04-25T17:26:32Z</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;
 *** twinklebatchdelete.js: Batch delete module (sysops only)&lt;br /&gt;
 ****************************************&lt;br /&gt;
 * Mode of invocation:     Tab (&amp;quot;D-batch&amp;quot;)&lt;br /&gt;
 * Active on:              Existing non-articles, and Special:PrefixIndex&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchdelete = function twinklebatchdelete() {&lt;br /&gt;
	if (&lt;br /&gt;
		Morebits.userIsSysop &amp;amp;&amp;amp; (&lt;br /&gt;
			(mw.config.get(&amp;#039;wgCurRevisionId&amp;#039;) &amp;amp;&amp;amp; mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;) &amp;gt; 0) ||&lt;br /&gt;
			mw.config.get(&amp;#039;wgCanonicalSpecialPageName&amp;#039;) === &amp;#039;Prefixindex&amp;#039;&lt;br /&gt;
		)&lt;br /&gt;
	) {&lt;br /&gt;
		Twinkle.addPortletLink(Twinkle.batchdelete.callback, &amp;#039;D-batch&amp;#039;, &amp;#039;tw-batch&amp;#039;, &amp;#039;Delete pages found in this category/on this page&amp;#039;);&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchdelete.unlinkCache = {};&lt;br /&gt;
&lt;br /&gt;
// Has the subpages list been loaded?&lt;br /&gt;
var subpagesLoaded;&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchdelete.callback = function twinklebatchdeleteCallback() {&lt;br /&gt;
	subpagesLoaded = false;&lt;br /&gt;
	var Window = new Morebits.simpleWindow(600, 400);&lt;br /&gt;
	Window.setTitle(&amp;#039;Batch deletion&amp;#039;);&lt;br /&gt;
	Window.setScriptName(&amp;#039;Twinkle&amp;#039;);&lt;br /&gt;
	Window.addFooterLink(&amp;#039;Twinkle help&amp;#039;, &amp;#039;WP:TW/DOC#batchdelete&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	var form = new Morebits.quickForm(Twinkle.batchdelete.callback.evaluate);&lt;br /&gt;
	form.append({&lt;br /&gt;
		type: &amp;#039;checkbox&amp;#039;,&lt;br /&gt;
		list: [&lt;br /&gt;
			{&lt;br /&gt;
				label: &amp;#039;Delete pages&amp;#039;,&lt;br /&gt;
				name: &amp;#039;delete_page&amp;#039;,&lt;br /&gt;
				value: &amp;#039;delete&amp;#039;,&lt;br /&gt;
				checked: true,&lt;br /&gt;
				subgroup: {&lt;br /&gt;
					type: &amp;#039;checkbox&amp;#039;,&lt;br /&gt;
					list: [&lt;br /&gt;
						{&lt;br /&gt;
							label: &amp;#039;Delete associated talk pages (except user talk pages)&amp;#039;,&lt;br /&gt;
							name: &amp;#039;delete_talk&amp;#039;,&lt;br /&gt;
							value: &amp;#039;delete_talk&amp;#039;,&lt;br /&gt;
							checked: true&lt;br /&gt;
						},&lt;br /&gt;
						{&lt;br /&gt;
							label: &amp;#039;Delete redirects to deleted pages&amp;#039;,&lt;br /&gt;
							name: &amp;#039;delete_redirects&amp;#039;,&lt;br /&gt;
							value: &amp;#039;delete_redirects&amp;#039;,&lt;br /&gt;
							checked: true&lt;br /&gt;
						},&lt;br /&gt;
						{&lt;br /&gt;
							label: &amp;#039;Delete subpages of deleted pages&amp;#039;,&lt;br /&gt;
							name: &amp;#039;delete_subpages&amp;#039;,&lt;br /&gt;
							value: &amp;#039;delete_subpages&amp;#039;,&lt;br /&gt;
							checked: false,&lt;br /&gt;
							event: Twinkle.batchdelete.callback.toggleSubpages,&lt;br /&gt;
							subgroup: {&lt;br /&gt;
								type: &amp;#039;checkbox&amp;#039;,&lt;br /&gt;
								list: [&lt;br /&gt;
									{&lt;br /&gt;
										label: &amp;#039;Delete talk pages of deleted subpages&amp;#039;,&lt;br /&gt;
										name: &amp;#039;delete_subpage_talks&amp;#039;,&lt;br /&gt;
										value: &amp;#039;delete_subpage_talks&amp;#039;&lt;br /&gt;
									},&lt;br /&gt;
									{&lt;br /&gt;
										label: &amp;#039;Delete redirects to deleted subpages&amp;#039;,&lt;br /&gt;
										name: &amp;#039;delete_subpage_redirects&amp;#039;,&lt;br /&gt;
										value: &amp;#039;delete_subpage_redirects&amp;#039;&lt;br /&gt;
									},&lt;br /&gt;
									{&lt;br /&gt;
										label: &amp;#039;Unlink backlinks to each deleted subpage (in Main and Portal namespaces only)&amp;#039;,&lt;br /&gt;
										name: &amp;#039;unlink_subpages&amp;#039;,&lt;br /&gt;
										value: &amp;#039;unlink_subpages&amp;#039;&lt;br /&gt;
									}&lt;br /&gt;
								]&lt;br /&gt;
							}&lt;br /&gt;
						}&lt;br /&gt;
					]&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				label: &amp;#039;Unlink backlinks to each page (in Main and Portal namespaces only)&amp;#039;,&lt;br /&gt;
				name: &amp;#039;unlink_page&amp;#039;,&lt;br /&gt;
				value: &amp;#039;unlink&amp;#039;,&lt;br /&gt;
				checked: false&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				label: &amp;#039;Remove usages of each file (in all namespaces)&amp;#039;,&lt;br /&gt;
				name: &amp;#039;unlink_file&amp;#039;,&lt;br /&gt;
				value: &amp;#039;unlink_file&amp;#039;,&lt;br /&gt;
				checked: true&lt;br /&gt;
			}&lt;br /&gt;
		]&lt;br /&gt;
	});&lt;br /&gt;
	form.append({&lt;br /&gt;
		type: &amp;#039;input&amp;#039;,&lt;br /&gt;
		name: &amp;#039;reason&amp;#039;,&lt;br /&gt;
		label: &amp;#039;Reason: &amp;#039;,&lt;br /&gt;
		size: 60&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
	var query = {&lt;br /&gt;
		&amp;#039;action&amp;#039;: &amp;#039;query&amp;#039;,&lt;br /&gt;
		&amp;#039;prop&amp;#039;: &amp;#039;revisions|info|imageinfo&amp;#039;,&lt;br /&gt;
		&amp;#039;inprop&amp;#039;: &amp;#039;protection&amp;#039;,&lt;br /&gt;
		&amp;#039;rvprop&amp;#039;: &amp;#039;size|user&amp;#039;&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	// On categories&lt;br /&gt;
	if (mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;) === 14) {&lt;br /&gt;
		query.generator = &amp;#039;categorymembers&amp;#039;;&lt;br /&gt;
		query.gcmtitle = mw.config.get(&amp;#039;wgPageName&amp;#039;);&lt;br /&gt;
		query.gcmlimit = Twinkle.getPref(&amp;#039;batchMax&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	// On Special:PrefixIndex&lt;br /&gt;
	} else if (mw.config.get(&amp;#039;wgCanonicalSpecialPageName&amp;#039;) === &amp;#039;Prefixindex&amp;#039;) {&lt;br /&gt;
&lt;br /&gt;
		query.generator = &amp;#039;allpages&amp;#039;;&lt;br /&gt;
		query.gaplimit = Twinkle.getPref(&amp;#039;batchMax&amp;#039;);&lt;br /&gt;
		if (mw.util.getParamValue(&amp;#039;prefix&amp;#039;)) {&lt;br /&gt;
			query.gapnamespace = mw.util.getParamValue(&amp;#039;namespace&amp;#039;);&lt;br /&gt;
			query.gapprefix = mw.util.getParamValue(&amp;#039;prefix&amp;#039;);&lt;br /&gt;
		} else {&lt;br /&gt;
			var pathSplit = decodeURIComponent(location.pathname).split(&amp;#039;/&amp;#039;);&lt;br /&gt;
			if (pathSplit.length &amp;lt; 3 || pathSplit[2] !== &amp;#039;Special:PrefixIndex&amp;#039;) {&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			var titleSplit = pathSplit[3].split(&amp;#039;:&amp;#039;);&lt;br /&gt;
			query.gapnamespace = mw.config.get(&amp;#039;wgNamespaceIds&amp;#039;)[titleSplit[0].toLowerCase()];&lt;br /&gt;
			if (titleSplit.length &amp;lt; 2 || typeof query.gapnamespace === &amp;#039;undefined&amp;#039;) {&lt;br /&gt;
				query.gapnamespace = 0;  // article namespace&lt;br /&gt;
				query.gapprefix = pathSplit.splice(3).join(&amp;#039;/&amp;#039;);&lt;br /&gt;
			} else {&lt;br /&gt;
				pathSplit = pathSplit.splice(4);&lt;br /&gt;
				pathSplit.splice(0, 0, titleSplit.splice(1).join(&amp;#039;:&amp;#039;));&lt;br /&gt;
				query.gapprefix = pathSplit.join(&amp;#039;/&amp;#039;);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	// On normal pages&lt;br /&gt;
	} else {&lt;br /&gt;
		query.generator = &amp;#039;links&amp;#039;;&lt;br /&gt;
		query.titles = mw.config.get(&amp;#039;wgPageName&amp;#039;);&lt;br /&gt;
		query.gpllimit = Twinkle.getPref(&amp;#039;batchMax&amp;#039;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	var statusdiv = document.createElement(&amp;#039;div&amp;#039;);&lt;br /&gt;
	statusdiv.style.padding = &amp;#039;15px&amp;#039;;  // just so it doesn&amp;#039;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;
	Twinkle.batchdelete.pages = {};&lt;br /&gt;
&lt;br /&gt;
	var statelem = new Morebits.status(&amp;#039;Grabbing list of pages&amp;#039;);&lt;br /&gt;
	var wikipedia_api = new Morebits.wiki.api(&amp;#039;loading...&amp;#039;, query, function(apiobj) {&lt;br /&gt;
		var xml = apiobj.responseXML;&lt;br /&gt;
		var $pages = $(xml).find(&amp;#039;page&amp;#039;).filter(&amp;#039;:not([missing])&amp;#039;);  // :not([imagerepository=&amp;quot;shared&amp;quot;])&lt;br /&gt;
		$pages.each(function(index, page) {&lt;br /&gt;
			var $page = $(page);&lt;br /&gt;
			var ns = $page.attr(&amp;#039;ns&amp;#039;);&lt;br /&gt;
			var title = $page.attr(&amp;#039;title&amp;#039;);&lt;br /&gt;
			var isRedir = $page.attr(&amp;#039;redirect&amp;#039;) === &amp;#039;&amp;#039;;&lt;br /&gt;
			var $editprot = $page.find(&amp;#039;pr[type=&amp;quot;edit&amp;quot;][level=&amp;quot;sysop&amp;quot;]&amp;#039;);&lt;br /&gt;
			var isProtected = $editprot.length &amp;gt; 0;&lt;br /&gt;
			var size = $page.find(&amp;#039;rev&amp;#039;).attr(&amp;#039;size&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
			var metadata = [];&lt;br /&gt;
			if (isRedir) {&lt;br /&gt;
				metadata.push(&amp;#039;redirect&amp;#039;);&lt;br /&gt;
			}&lt;br /&gt;
			if (isProtected) {&lt;br /&gt;
				metadata.push(&amp;#039;fully protected&amp;#039; +&lt;br /&gt;
				($editprot.attr(&amp;#039;expiry&amp;#039;) === &amp;#039;infinity&amp;#039; ? &amp;#039; indefinitely&amp;#039; : &amp;#039;, expires &amp;#039; + new Morebits.date($editprot.attr(&amp;#039;expiry&amp;#039;)).calendar(&amp;#039;utc&amp;#039;) + &amp;#039; (UTC)&amp;#039;));&lt;br /&gt;
			}&lt;br /&gt;
			if (ns === &amp;#039;6&amp;#039;) {  // mimic what delimages used to show for files&lt;br /&gt;
				metadata.push(&amp;#039;uploader: &amp;#039; + $page.find(&amp;#039;ii&amp;#039;).attr(&amp;#039;user&amp;#039;));&lt;br /&gt;
				metadata.push(&amp;#039;last edit from: &amp;#039; + $page.find(&amp;#039;rev&amp;#039;).attr(&amp;#039;user&amp;#039;));&lt;br /&gt;
			} else {&lt;br /&gt;
				metadata.push(size + &amp;#039; bytes&amp;#039;);&lt;br /&gt;
			}&lt;br /&gt;
			Twinkle.batchdelete.pages[title] = {&lt;br /&gt;
				label: title + (metadata.length ? &amp;#039; (&amp;#039; + metadata.join(&amp;#039;; &amp;#039;) + &amp;#039;)&amp;#039; : &amp;#039;&amp;#039;),&lt;br /&gt;
				value: title,&lt;br /&gt;
				checked: true,&lt;br /&gt;
				style: isProtected ? &amp;#039;color:red&amp;#039; : &amp;#039;&amp;#039;&lt;br /&gt;
			};&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		var form = apiobj.params.form;&lt;br /&gt;
		form.append({ type: &amp;#039;header&amp;#039;, label: &amp;#039;Pages to delete&amp;#039; });&lt;br /&gt;
		form.append({&lt;br /&gt;
			type: &amp;#039;button&amp;#039;,&lt;br /&gt;
			label: &amp;#039;Select All&amp;#039;,&lt;br /&gt;
			event: function dBatchSelectAll() {&lt;br /&gt;
				$(result).find(&amp;#039;input[name=pages]:not(:checked)&amp;#039;).each(function(_, e) {&lt;br /&gt;
					e.click(); // check it, and invoke click event so that subgroup can be shown&lt;br /&gt;
				});&lt;br /&gt;
&lt;br /&gt;
				// Check any unchecked subpages too&lt;br /&gt;
				$(&amp;#039;input[name=&amp;quot;pages.subpages&amp;quot;]&amp;#039;).prop(&amp;#039;checked&amp;#039;, true);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		form.append({&lt;br /&gt;
			type: &amp;#039;button&amp;#039;,&lt;br /&gt;
			label: &amp;#039;Deselect All&amp;#039;,&lt;br /&gt;
			event: function dBatchDeselectAll() {&lt;br /&gt;
				$(result).find(&amp;#039;input[name=pages]:checked&amp;#039;).each(function(_, e) {&lt;br /&gt;
					e.click(); // uncheck it, and invoke click event so that subgroup can be hidden&lt;br /&gt;
				});&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
		form.append({&lt;br /&gt;
			type: &amp;#039;checkbox&amp;#039;,&lt;br /&gt;
			name: &amp;#039;pages&amp;#039;,&lt;br /&gt;
			id: &amp;#039;tw-dbatch-pages&amp;#039;,&lt;br /&gt;
			list: $.map(Twinkle.batchdelete.pages, function (e) {&lt;br /&gt;
				return e;&lt;br /&gt;
			})&lt;br /&gt;
		});&lt;br /&gt;
		form.append({ type: &amp;#039;submit&amp;#039; });&lt;br /&gt;
&lt;br /&gt;
		var result = form.render();&lt;br /&gt;
		apiobj.params.Window.setContent(result);&lt;br /&gt;
&lt;br /&gt;
		var pageCheckboxes = Morebits.quickForm.getElements(result, &amp;#039;pages&amp;#039;) || [];&lt;br /&gt;
		pageCheckboxes.forEach(generateArrowLinks);&lt;br /&gt;
		Morebits.checkboxShiftClickSupport(pageCheckboxes);&lt;br /&gt;
&lt;br /&gt;
	}, statelem);&lt;br /&gt;
&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;
function generateArrowLinks (checkbox) {&lt;br /&gt;
	var link = Morebits.htmlNode(&amp;#039;a&amp;#039;, &amp;#039; &amp;gt;&amp;#039;);&lt;br /&gt;
	link.setAttribute(&amp;#039;class&amp;#039;, &amp;#039;tw-dbatch-page-link&amp;#039;);&lt;br /&gt;
	link.setAttribute(&amp;#039;href&amp;#039;, mw.util.getUrl(checkbox.value));&lt;br /&gt;
	link.setAttribute(&amp;#039;target&amp;#039;, &amp;#039;_blank&amp;#039;);&lt;br /&gt;
	checkbox.nextElementSibling.append(link);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchdelete.generateNewPageList = function(form) {&lt;br /&gt;
&lt;br /&gt;
	// Update the list of checked pages in Twinkle.batchdelete.pages object&lt;br /&gt;
	var elements = form.elements.pages;&lt;br /&gt;
	if (elements instanceof NodeList) { // if there are multiple pages&lt;br /&gt;
		for (var i = 0; i &amp;lt; elements.length; ++i) {&lt;br /&gt;
			Twinkle.batchdelete.pages[elements[i].value].checked = elements[i].checked;&lt;br /&gt;
		}&lt;br /&gt;
	} else if (elements instanceof HTMLInputElement) { // if there is just one page&lt;br /&gt;
		Twinkle.batchdelete.pages[elements.value].checked = elements.checked;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return new Morebits.quickForm.element({&lt;br /&gt;
		type: &amp;#039;checkbox&amp;#039;,&lt;br /&gt;
		name: &amp;#039;pages&amp;#039;,&lt;br /&gt;
		id: &amp;#039;tw-dbatch-pages&amp;#039;,&lt;br /&gt;
		list: $.map(Twinkle.batchdelete.pages, function (e) {&lt;br /&gt;
			return e;&lt;br /&gt;
		})&lt;br /&gt;
	}).render();&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchdelete.callback.toggleSubpages = function twDbatchToggleSubpages(e) {&lt;br /&gt;
&lt;br /&gt;
	var form = e.target.form;&lt;br /&gt;
	var newPageList, pageCheckboxes, subpageCheckboxes;&lt;br /&gt;
&lt;br /&gt;
	if (e.target.checked) {&lt;br /&gt;
&lt;br /&gt;
		form.delete_subpage_redirects.checked = form.delete_redirects.checked;&lt;br /&gt;
		form.delete_subpage_talks.checked = form.delete_talk.checked;&lt;br /&gt;
		form.unlink_subpages.checked = form.unlink_page.checked;&lt;br /&gt;
&lt;br /&gt;
		// If lists of subpages were already loaded once, they are&lt;br /&gt;
		// available without use of any API calls&lt;br /&gt;
		if (subpagesLoaded) {&lt;br /&gt;
&lt;br /&gt;
			$.each(Twinkle.batchdelete.pages, function(i, el) {&lt;br /&gt;
				// Get back the subgroup from subgroup_, where we saved it&lt;br /&gt;
				if (el.subgroup === null &amp;amp;&amp;amp; el.subgroup_) {&lt;br /&gt;
					el.subgroup = el.subgroup_;&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			newPageList = Twinkle.batchdelete.generateNewPageList(form);&lt;br /&gt;
			$(&amp;#039;#tw-dbatch-pages&amp;#039;).replaceWith(newPageList);&lt;br /&gt;
&lt;br /&gt;
			pageCheckboxes = Morebits.quickForm.getElements(newPageList, &amp;#039;pages&amp;#039;) || [];&lt;br /&gt;
			pageCheckboxes.forEach(generateArrowLinks);&lt;br /&gt;
			Morebits.checkboxShiftClickSupport(pageCheckboxes);&lt;br /&gt;
&lt;br /&gt;
			subpageCheckboxes = Morebits.quickForm.getElements(newPageList, &amp;#039;pages.subpages&amp;#039;) || [];&lt;br /&gt;
			subpageCheckboxes.forEach(generateArrowLinks);&lt;br /&gt;
			Morebits.checkboxShiftClickSupport(subpageCheckboxes);&lt;br /&gt;
&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Proceed with API calls to get list of subpages&lt;br /&gt;
		var loadingText = &amp;#039;&amp;lt;strong id=&amp;quot;dbatch-subpage-loading&amp;quot;&amp;gt;Loading... &amp;lt;/strong&amp;gt;&amp;#039;;&lt;br /&gt;
		$(e.target).after(loadingText);&lt;br /&gt;
&lt;br /&gt;
		var pages = $(form.pages).map(function(i, el) {&lt;br /&gt;
			return el.value;&lt;br /&gt;
		}).get();&lt;br /&gt;
&lt;br /&gt;
		var subpageLister = new Morebits.batchOperation();&lt;br /&gt;
		subpageLister.setOption(&amp;#039;chunkSize&amp;#039;, Twinkle.getPref(&amp;#039;batchdeleteChunks&amp;#039;));&lt;br /&gt;
		subpageLister.setPageList(pages);&lt;br /&gt;
		subpageLister.run(function worker (pageName) {&lt;br /&gt;
			var pageTitle = mw.Title.newFromText(pageName);&lt;br /&gt;
&lt;br /&gt;
			// No need to look for subpages in main/file/mediawiki space&lt;br /&gt;
			if ([0, 6, 8].indexOf(pageTitle.namespace) &amp;gt; -1) {&lt;br /&gt;
				subpageLister.workerSuccess();&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			var wikipedia_api = new Morebits.wiki.api(&amp;#039;Getting list of subpages of &amp;#039; + pageName, {&lt;br /&gt;
				action: &amp;#039;query&amp;#039;,&lt;br /&gt;
				prop: &amp;#039;revisions|info|imageinfo&amp;#039;,&lt;br /&gt;
				generator: &amp;#039;allpages&amp;#039;,&lt;br /&gt;
				rvprop: &amp;#039;size&amp;#039;,&lt;br /&gt;
				inprop: &amp;#039;protection&amp;#039;,&lt;br /&gt;
				gapprefix: pageTitle.title + &amp;#039;/&amp;#039;,&lt;br /&gt;
				gapnamespace: pageTitle.namespace,&lt;br /&gt;
				gaplimit: &amp;#039;max&amp;#039;, // 500 is max for normal users, 5000 for bots and sysops&lt;br /&gt;
				pageNameFull: pageName // Not used by API, but added for access in onSuccess()&lt;br /&gt;
			}, function onSuccess(apiobj) {&lt;br /&gt;
				var xml = apiobj.responseXML;&lt;br /&gt;
				var $pages = $(xml).find(&amp;#039;page&amp;#039;);&lt;br /&gt;
				var subpageList = [];&lt;br /&gt;
				$pages.each(function(index, page) {&lt;br /&gt;
					var $page = $(page);&lt;br /&gt;
					var ns = $page.attr(&amp;#039;ns&amp;#039;);&lt;br /&gt;
					var title = $page.attr(&amp;#039;title&amp;#039;);&lt;br /&gt;
					var isRedir = $page.attr(&amp;#039;redirect&amp;#039;) === &amp;#039;&amp;#039;;&lt;br /&gt;
					var $editprot = $page.find(&amp;#039;pr[type=&amp;quot;edit&amp;quot;][level=&amp;quot;sysop&amp;quot;]&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
					var isProtected = $editprot.length &amp;gt; 0;&lt;br /&gt;
					var size = $page.find(&amp;#039;rev&amp;#039;).attr(&amp;#039;size&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
					var metadata = [];&lt;br /&gt;
					if (isRedir) {&lt;br /&gt;
						metadata.push(&amp;#039;redirect&amp;#039;);&lt;br /&gt;
					}&lt;br /&gt;
					if (isProtected) {&lt;br /&gt;
						metadata.push(&amp;#039;fully protected&amp;#039; +&lt;br /&gt;
						($editprot.attr(&amp;#039;expiry&amp;#039;) === &amp;#039;infinity&amp;#039; ? &amp;#039; indefinitely&amp;#039; : &amp;#039;, expires &amp;#039; + new Morebits.date($editprot.attr(&amp;#039;expiry&amp;#039;)).calendar(&amp;#039;utc&amp;#039;) + &amp;#039; (UTC)&amp;#039;));&lt;br /&gt;
					}&lt;br /&gt;
					if (ns === &amp;#039;6&amp;#039;) {  // mimic what delimages used to show for files&lt;br /&gt;
						metadata.push(&amp;#039;uploader: &amp;#039; + $page.find(&amp;#039;ii&amp;#039;).attr(&amp;#039;user&amp;#039;));&lt;br /&gt;
						metadata.push(&amp;#039;last edit from: &amp;#039; + $page.find(&amp;#039;rev&amp;#039;).attr(&amp;#039;user&amp;#039;));&lt;br /&gt;
					} else {&lt;br /&gt;
						metadata.push(size + &amp;#039; bytes&amp;#039;);&lt;br /&gt;
					}&lt;br /&gt;
					subpageList.push({&lt;br /&gt;
						label: title + (metadata.length ? &amp;#039; (&amp;#039; + metadata.join(&amp;#039;; &amp;#039;) + &amp;#039;)&amp;#039; : &amp;#039;&amp;#039;),&lt;br /&gt;
						value: title,&lt;br /&gt;
						checked: true,&lt;br /&gt;
						style: isProtected ? &amp;#039;color:red&amp;#039; : &amp;#039;&amp;#039;&lt;br /&gt;
					});&lt;br /&gt;
				});&lt;br /&gt;
				if (subpageList.length) {&lt;br /&gt;
					var pageName = apiobj.query.pageNameFull;&lt;br /&gt;
					Twinkle.batchdelete.pages[pageName].subgroup = {&lt;br /&gt;
						type: &amp;#039;checkbox&amp;#039;,&lt;br /&gt;
						name: &amp;#039;subpages&amp;#039;,&lt;br /&gt;
						className: &amp;#039;dbatch-subpages&amp;#039;,&lt;br /&gt;
						list: subpageList&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
				subpageLister.workerSuccess();&lt;br /&gt;
			}, null /* statusElement */, function onFailure() {&lt;br /&gt;
				subpageLister.workerFailure();&lt;br /&gt;
			});&lt;br /&gt;
			wikipedia_api.post();&lt;br /&gt;
&lt;br /&gt;
		}, function postFinish () {&lt;br /&gt;
			// List &amp;#039;em on the interface&lt;br /&gt;
&lt;br /&gt;
			newPageList = Twinkle.batchdelete.generateNewPageList(form);&lt;br /&gt;
			$(&amp;#039;#tw-dbatch-pages&amp;#039;).replaceWith(newPageList);&lt;br /&gt;
&lt;br /&gt;
			pageCheckboxes = Morebits.quickForm.getElements(newPageList, &amp;#039;pages&amp;#039;) || [];&lt;br /&gt;
			pageCheckboxes.forEach(generateArrowLinks);&lt;br /&gt;
			Morebits.checkboxShiftClickSupport(pageCheckboxes);&lt;br /&gt;
&lt;br /&gt;
			subpageCheckboxes = Morebits.quickForm.getElements(newPageList, &amp;#039;pages.subpages&amp;#039;) || [];&lt;br /&gt;
			subpageCheckboxes.forEach(generateArrowLinks);&lt;br /&gt;
			Morebits.checkboxShiftClickSupport(subpageCheckboxes);&lt;br /&gt;
&lt;br /&gt;
			subpagesLoaded = true;&lt;br /&gt;
&lt;br /&gt;
			// Remove &amp;quot;Loading... &amp;quot; text&lt;br /&gt;
			$(&amp;#039;#dbatch-subpage-loading&amp;#039;).remove();&lt;br /&gt;
&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	} else if (!e.target.checked) {&lt;br /&gt;
&lt;br /&gt;
		$.each(Twinkle.batchdelete.pages, function(i, el) {&lt;br /&gt;
			if (el.subgroup) {&lt;br /&gt;
				// Remove subgroup after saving its contents in subgroup_&lt;br /&gt;
				// so that it can be retrieved easily if user decides to&lt;br /&gt;
				// delete the subpages again&lt;br /&gt;
				el.subgroup_ = el.subgroup;&lt;br /&gt;
				el.subgroup = null;&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		newPageList = Twinkle.batchdelete.generateNewPageList(form);&lt;br /&gt;
		$(&amp;#039;#tw-dbatch-pages&amp;#039;).replaceWith(newPageList);&lt;br /&gt;
&lt;br /&gt;
		pageCheckboxes = Morebits.quickForm.getElements(newPageList, &amp;#039;pages&amp;#039;) || [];&lt;br /&gt;
		pageCheckboxes.forEach(generateArrowLinks);&lt;br /&gt;
		Morebits.checkboxShiftClickSupport(pageCheckboxes);&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchdelete.callback.evaluate = function twinklebatchdeleteCallbackEvaluate(event) {&lt;br /&gt;
	Morebits.wiki.actionCompleted.notice = &amp;#039;Batch deletion is now complete&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
	var form = event.target;&lt;br /&gt;
&lt;br /&gt;
	var numProtected = $(Morebits.quickForm.getElements(form, &amp;#039;pages&amp;#039;)).filter(function(index, element) {&lt;br /&gt;
		return element.checked &amp;amp;&amp;amp; element.nextElementSibling.style.color === &amp;#039;red&amp;#039;;&lt;br /&gt;
	}).length;&lt;br /&gt;
	if (numProtected &amp;gt; 0 &amp;amp;&amp;amp; !confirm(&amp;#039;You are about to delete &amp;#039; + numProtected + &amp;#039; fully protected page(s). Are you sure?&amp;#039;)) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	var pages = form.getChecked(&amp;#039;pages&amp;#039;);&lt;br /&gt;
	var subpages = form.getChecked(&amp;#039;pages.subpages&amp;#039;);&lt;br /&gt;
	var reason = form.reason.value;&lt;br /&gt;
	var delete_page = form.delete_page.checked;&lt;br /&gt;
	var delete_talk, delete_redirects, delete_subpages;&lt;br /&gt;
	var delete_subpage_redirects, delete_subpage_talks, unlink_subpages;&lt;br /&gt;
	if (delete_page) {&lt;br /&gt;
		delete_talk = form.delete_talk.checked;&lt;br /&gt;
		delete_redirects = form.delete_redirects.checked;&lt;br /&gt;
		delete_subpages = form.delete_subpages.checked;&lt;br /&gt;
		if (delete_subpages) {&lt;br /&gt;
			delete_subpage_redirects = form.delete_subpage_redirects.checked;&lt;br /&gt;
			delete_subpage_talks = form.delete_subpage_talks.checked;&lt;br /&gt;
			unlink_subpages = form.unlink_subpages.checked;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	var unlink_page = form.unlink_page.checked;&lt;br /&gt;
	var unlink_file = form.unlink_file.checked;&lt;br /&gt;
	if (!reason) {&lt;br /&gt;
		alert(&amp;#039;You need to give a reason, you cabal crony!&amp;#039;);&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	Morebits.simpleWindow.setButtonsEnabled(false);&lt;br /&gt;
	Morebits.status.init(form);&lt;br /&gt;
	if (!pages) {&lt;br /&gt;
		Morebits.status.error(&amp;#039;Error&amp;#039;, &amp;#039;nothing to delete, aborting&amp;#039;);&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	var pageDeleter = new Morebits.batchOperation(delete_page ? &amp;#039;Deleting pages&amp;#039; : &amp;#039;Initiating requested tasks&amp;#039;);&lt;br /&gt;
	pageDeleter.setOption(&amp;#039;chunkSize&amp;#039;, Twinkle.getPref(&amp;#039;batchdeleteChunks&amp;#039;));&lt;br /&gt;
	// we only need the initial status lines if we&amp;#039;re deleting the pages in the pages array&lt;br /&gt;
	pageDeleter.setOption(&amp;#039;preserveIndividualStatusLines&amp;#039;, delete_page);&lt;br /&gt;
	pageDeleter.setPageList(pages);&lt;br /&gt;
	pageDeleter.run(function worker(pageName) {&lt;br /&gt;
		var params = {&lt;br /&gt;
			page: pageName,&lt;br /&gt;
			delete_page: delete_page,&lt;br /&gt;
			delete_talk: delete_talk,&lt;br /&gt;
			delete_redirects: delete_redirects,&lt;br /&gt;
			unlink_page: unlink_page,&lt;br /&gt;
			unlink_file: unlink_file &amp;amp;&amp;amp; /^(File|Image):/i.test(pageName),&lt;br /&gt;
			reason: reason,&lt;br /&gt;
			pageDeleter: pageDeleter&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		var wikipedia_page = new Morebits.wiki.page(pageName, &amp;#039;Deleting page &amp;#039; + pageName);&lt;br /&gt;
		wikipedia_page.setCallbackParameters(params);&lt;br /&gt;
		if (delete_page) {&lt;br /&gt;
			wikipedia_page.setEditSummary(reason + Twinkle.getPref(&amp;#039;deletionSummaryAd&amp;#039;));&lt;br /&gt;
			wikipedia_page.suppressProtectWarning();&lt;br /&gt;
			wikipedia_page.deletePage(Twinkle.batchdelete.callbacks.doExtras, pageDeleter.workerFailure);&lt;br /&gt;
		} else {&lt;br /&gt;
			Twinkle.batchdelete.callbacks.doExtras(wikipedia_page);&lt;br /&gt;
		}&lt;br /&gt;
	}, function postFinish() {&lt;br /&gt;
		if (delete_subpages) {&lt;br /&gt;
			var subpageDeleter = new Morebits.batchOperation(&amp;#039;Deleting subpages&amp;#039;);&lt;br /&gt;
			subpageDeleter.setOption(&amp;#039;chunkSize&amp;#039;, Twinkle.getPref(&amp;#039;batchdeleteChunks&amp;#039;));&lt;br /&gt;
			subpageDeleter.setOption(&amp;#039;preserveIndividualStatusLines&amp;#039;, true);&lt;br /&gt;
			subpageDeleter.setPageList(subpages);&lt;br /&gt;
			subpageDeleter.run(function(pageName) {&lt;br /&gt;
				var params = {&lt;br /&gt;
					page: pageName,&lt;br /&gt;
					delete_page: true,&lt;br /&gt;
					delete_talk: delete_subpage_talks,&lt;br /&gt;
					delete_redirects: delete_subpage_redirects,&lt;br /&gt;
					unlink_page: unlink_subpages,&lt;br /&gt;
					unlink_file: false,&lt;br /&gt;
					reason: reason,&lt;br /&gt;
					pageDeleter: subpageDeleter&lt;br /&gt;
				};&lt;br /&gt;
&lt;br /&gt;
				var wikipedia_page = new Morebits.wiki.page(pageName, &amp;#039;Deleting subpage &amp;#039; + pageName);&lt;br /&gt;
				wikipedia_page.setCallbackParameters(params);&lt;br /&gt;
				wikipedia_page.setEditSummary(reason + Twinkle.getPref(&amp;#039;deletionSummaryAd&amp;#039;));&lt;br /&gt;
				wikipedia_page.suppressProtectWarning();&lt;br /&gt;
				wikipedia_page.deletePage(Twinkle.batchdelete.callbacks.doExtras, pageDeleter.workerFailure);&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
	});&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchdelete.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&amp;#039;s job is to delete the page, and that has&lt;br /&gt;
		// succeeded by now&lt;br /&gt;
		params.pageDeleter.workerSuccess(thingWithParameters);&lt;br /&gt;
&lt;br /&gt;
		var query, wikipedia_api;&lt;br /&gt;
&lt;br /&gt;
		if (params.unlink_page) {&lt;br /&gt;
			Twinkle.batchdelete.unlinkCache = {};&lt;br /&gt;
			query = {&lt;br /&gt;
				&amp;#039;action&amp;#039;: &amp;#039;query&amp;#039;,&lt;br /&gt;
				&amp;#039;list&amp;#039;: &amp;#039;backlinks&amp;#039;,&lt;br /&gt;
				&amp;#039;blfilterredir&amp;#039;: &amp;#039;nonredirects&amp;#039;,&lt;br /&gt;
				&amp;#039;blnamespace&amp;#039;: [0, 100], // main space and portal space only&lt;br /&gt;
				&amp;#039;bltitle&amp;#039;: params.page,&lt;br /&gt;
				&amp;#039;bllimit&amp;#039;: &amp;#039;max&amp;#039; // 500 is max for normal users, 5000 for bots and sysops&lt;br /&gt;
			};&lt;br /&gt;
			wikipedia_api = new Morebits.wiki.api(&amp;#039;Grabbing backlinks&amp;#039;, query, Twinkle.batchdelete.callbacks.unlinkBacklinksMain);&lt;br /&gt;
			wikipedia_api.params = params;&lt;br /&gt;
			wikipedia_api.post();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (params.unlink_file) {&lt;br /&gt;
			query = {&lt;br /&gt;
				&amp;#039;action&amp;#039;: &amp;#039;query&amp;#039;,&lt;br /&gt;
				&amp;#039;list&amp;#039;: &amp;#039;imageusage&amp;#039;,&lt;br /&gt;
				&amp;#039;iutitle&amp;#039;: params.page,&lt;br /&gt;
				&amp;#039;iulimit&amp;#039;: &amp;#039;max&amp;#039; // 500 is max for normal users, 5000 for bots and sysops&lt;br /&gt;
			};&lt;br /&gt;
			wikipedia_api = new Morebits.wiki.api(&amp;#039;Grabbing file links&amp;#039;, query, Twinkle.batchdelete.callbacks.unlinkImageInstancesMain);&lt;br /&gt;
			wikipedia_api.params = params;&lt;br /&gt;
			wikipedia_api.post();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (params.delete_page) {&lt;br /&gt;
			if (params.delete_redirects) {&lt;br /&gt;
				query = {&lt;br /&gt;
					&amp;#039;action&amp;#039;: &amp;#039;query&amp;#039;,&lt;br /&gt;
					&amp;#039;titles&amp;#039;: params.page,&lt;br /&gt;
					&amp;#039;prop&amp;#039;: &amp;#039;redirects&amp;#039;,&lt;br /&gt;
					&amp;#039;rdlimit&amp;#039;: &amp;#039;max&amp;#039; // 500 is max for normal users, 5000 for bots and sysops&lt;br /&gt;
				};&lt;br /&gt;
				wikipedia_api = new Morebits.wiki.api(&amp;#039;Grabbing redirects&amp;#039;, query, Twinkle.batchdelete.callbacks.deleteRedirectsMain);&lt;br /&gt;
				wikipedia_api.params = params;&lt;br /&gt;
				wikipedia_api.post();&lt;br /&gt;
			}&lt;br /&gt;
			if (params.delete_talk) {&lt;br /&gt;
				var pageTitle = mw.Title.newFromText(params.page);&lt;br /&gt;
				if (pageTitle &amp;amp;&amp;amp; pageTitle.namespace % 2 === 0 &amp;amp;&amp;amp; pageTitle.namespace !== 2) {&lt;br /&gt;
					pageTitle.namespace++;  // now pageTitle is the talk page title!&lt;br /&gt;
					query = {&lt;br /&gt;
						&amp;#039;action&amp;#039;: &amp;#039;query&amp;#039;,&lt;br /&gt;
						&amp;#039;titles&amp;#039;: pageTitle.toText()&lt;br /&gt;
					};&lt;br /&gt;
					wikipedia_api = new Morebits.wiki.api(&amp;#039;Checking whether talk page exists&amp;#039;, query, Twinkle.batchdelete.callbacks.deleteTalk);&lt;br /&gt;
					wikipedia_api.params = params;&lt;br /&gt;
					wikipedia_api.params.talkPage = pageTitle.toText();&lt;br /&gt;
					wikipedia_api.post();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	deleteRedirectsMain: function(apiobj) {&lt;br /&gt;
		var xml = apiobj.responseXML;&lt;br /&gt;
		var pages = $(xml).find(&amp;#039;rd&amp;#039;).map(function() {&lt;br /&gt;
			return $(this).attr(&amp;#039;title&amp;#039;);&lt;br /&gt;
		}).get();&lt;br /&gt;
		if (!pages.length) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var redirectDeleter = new Morebits.batchOperation(&amp;#039;Deleting redirects to &amp;#039; + apiobj.params.page);&lt;br /&gt;
		redirectDeleter.setOption(&amp;#039;chunkSize&amp;#039;, Twinkle.getPref(&amp;#039;batchdeleteChunks&amp;#039;));&lt;br /&gt;
		redirectDeleter.setPageList(pages);&lt;br /&gt;
		redirectDeleter.run(function(pageName) {&lt;br /&gt;
			var wikipedia_page = new Morebits.wiki.page(pageName, &amp;#039;Deleting &amp;#039; + pageName);&lt;br /&gt;
			wikipedia_page.setEditSummary(&amp;#039;[[WP:CSD#G8|G8]]: Redirect to deleted page &amp;quot;&amp;#039; + apiobj.params.page + &amp;#039;&amp;quot;&amp;#039; + Twinkle.getPref(&amp;#039;deletionSummaryAd&amp;#039;));&lt;br /&gt;
			wikipedia_page.deletePage(redirectDeleter.workerSuccess, redirectDeleter.workerFailure);&lt;br /&gt;
		});&lt;br /&gt;
	},&lt;br /&gt;
	deleteTalk: function(apiobj) {&lt;br /&gt;
		var xml = apiobj.responseXML;&lt;br /&gt;
		var exists = $(xml).find(&amp;#039;page:not([missing])&amp;#039;).length &amp;gt; 0;&lt;br /&gt;
&lt;br /&gt;
		if (!exists) {&lt;br /&gt;
			// no talk page; 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, &amp;#039;Deleting talk page of article &amp;#039; + apiobj.params.page);&lt;br /&gt;
		page.setEditSummary(&amp;#039;[[WP:CSD#G8|G8]]: [[Help:Talk page|Talk page]] of deleted page &amp;quot;&amp;#039; + apiobj.params.page + &amp;#039;&amp;quot;&amp;#039; + Twinkle.getPref(&amp;#039;deletionSummaryAd&amp;#039;));&lt;br /&gt;
		page.deletePage();&lt;br /&gt;
	},&lt;br /&gt;
	unlinkBacklinksMain: function(apiobj) {&lt;br /&gt;
		var xml = apiobj.responseXML;&lt;br /&gt;
		var pages = $(xml).find(&amp;#039;bl&amp;#039;).map(function() {&lt;br /&gt;
			return $(this).attr(&amp;#039;title&amp;#039;);&lt;br /&gt;
		}).get();&lt;br /&gt;
		if (!pages.length) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var unlinker = new Morebits.batchOperation(&amp;#039;Unlinking backlinks to &amp;#039; + apiobj.params.page);&lt;br /&gt;
		unlinker.setOption(&amp;#039;chunkSize&amp;#039;, Twinkle.getPref(&amp;#039;batchdeleteChunks&amp;#039;));&lt;br /&gt;
		unlinker.setPageList(pages);&lt;br /&gt;
		unlinker.run(function(pageName) {&lt;br /&gt;
			var wikipedia_page = new Morebits.wiki.page(pageName, &amp;#039;Unlinking on &amp;#039; + pageName);&lt;br /&gt;
			var params = $.extend({}, apiobj.params);&lt;br /&gt;
			params.title = pageName;&lt;br /&gt;
			params.unlinker = unlinker;&lt;br /&gt;
			wikipedia_page.setCallbackParameters(params);&lt;br /&gt;
			wikipedia_page.load(Twinkle.batchdelete.callbacks.unlinkBacklinks);&lt;br /&gt;
		});&lt;br /&gt;
	},&lt;br /&gt;
	unlinkBacklinks: function(pageobj) {&lt;br /&gt;
		var params = pageobj.getCallbackParameters();&lt;br /&gt;
		if (!pageobj.exists()) {&lt;br /&gt;
			// we probably just deleted it, as a recursive backlink&lt;br /&gt;
			params.unlinker.workerSuccess(pageobj);&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var text;&lt;br /&gt;
		if (params.title in Twinkle.batchdelete.unlinkCache) {&lt;br /&gt;
			text = Twinkle.batchdelete.unlinkCache[params.title];&lt;br /&gt;
		} else {&lt;br /&gt;
			text = pageobj.getPageText();&lt;br /&gt;
		}&lt;br /&gt;
		var old_text = text;&lt;br /&gt;
		var wikiPage = new Morebits.wikitext.page(text);&lt;br /&gt;
		wikiPage.removeLink(params.page);&lt;br /&gt;
&lt;br /&gt;
		text = wikiPage.getText();&lt;br /&gt;
		Twinkle.batchdelete.unlinkCache[params.title] = text;&lt;br /&gt;
		if (text === old_text) {&lt;br /&gt;
			// Nothing to do, return&lt;br /&gt;
			params.unlinker.workerSuccess(pageobj);&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
		pageobj.setEditSummary(&amp;#039;Removing link(s) to deleted page &amp;#039; + params.page + Twinkle.getPref(&amp;#039;deletionSummaryAd&amp;#039;));&lt;br /&gt;
		pageobj.setPageText(text);&lt;br /&gt;
		pageobj.setCreateOption(&amp;#039;nocreate&amp;#039;);&lt;br /&gt;
		pageobj.setMaxConflictRetries(10);&lt;br /&gt;
		pageobj.save(params.unlinker.workerSuccess, params.unlinker.workerFailure);&lt;br /&gt;
	},&lt;br /&gt;
	unlinkImageInstancesMain: function(apiobj) {&lt;br /&gt;
		var xml = apiobj.responseXML;&lt;br /&gt;
		var pages = $(xml).find(&amp;#039;iu&amp;#039;).map(function() {&lt;br /&gt;
			return $(this).attr(&amp;#039;title&amp;#039;);&lt;br /&gt;
		}).get();&lt;br /&gt;
		if (!pages.length) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var unlinker = new Morebits.batchOperation(&amp;#039;Unlinking backlinks to &amp;#039; + apiobj.params.page);&lt;br /&gt;
		unlinker.setOption(&amp;#039;chunkSize&amp;#039;, Twinkle.getPref(&amp;#039;batchdeleteChunks&amp;#039;));&lt;br /&gt;
		unlinker.setPageList(pages);&lt;br /&gt;
		unlinker.run(function(pageName) {&lt;br /&gt;
			var wikipedia_page = new Morebits.wiki.page(pageName, &amp;#039;Removing file usages on &amp;#039; + pageName);&lt;br /&gt;
			var params = $.extend({}, apiobj.params);&lt;br /&gt;
			params.title = pageName;&lt;br /&gt;
			params.unlinker = unlinker;&lt;br /&gt;
			wikipedia_page.setCallbackParameters(params);&lt;br /&gt;
			wikipedia_page.load(Twinkle.batchdelete.callbacks.unlinkImageInstances);&lt;br /&gt;
		});&lt;br /&gt;
	},&lt;br /&gt;
	unlinkImageInstances: function(pageobj) {&lt;br /&gt;
		var params = pageobj.getCallbackParameters();&lt;br /&gt;
		if (!pageobj.exists()) {&lt;br /&gt;
			// we probably just deleted it, as a recursive backlink&lt;br /&gt;
			params.unlinker.workerSuccess(pageobj);&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var image = params.page.replace(/^(?:Image|File):/, &amp;#039;&amp;#039;);&lt;br /&gt;
		var text;&lt;br /&gt;
		if (params.title in Twinkle.batchdelete.unlinkCache) {&lt;br /&gt;
			text = Twinkle.batchdelete.unlinkCache[params.title];&lt;br /&gt;
		} else {&lt;br /&gt;
			text = pageobj.getPageText();&lt;br /&gt;
		}&lt;br /&gt;
		var old_text = text;&lt;br /&gt;
		var wikiPage = new Morebits.wikitext.page(text);&lt;br /&gt;
		wikiPage.commentOutImage(image, &amp;#039;Commented out because image was deleted&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
		text = wikiPage.getText();&lt;br /&gt;
		Twinkle.batchdelete.unlinkCache[params.title] = text;&lt;br /&gt;
		if (text === old_text) {&lt;br /&gt;
			pageobj.getStatusElement().error(&amp;#039;failed to unlink image &amp;#039; + image + &amp;#039; from &amp;#039; + pageobj.getPageName());&lt;br /&gt;
			params.unlinker.workerFailure(pageobj);&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
		pageobj.setEditSummary(&amp;#039;Removing instance of file &amp;#039; + image + &amp;#039; that has been deleted because &amp;quot;&amp;#039; + params.reason + &amp;#039;&amp;quot;)&amp;#039; + Twinkle.getPref(&amp;#039;deletionSummaryAd&amp;#039;));&lt;br /&gt;
		pageobj.setPageText(text);&lt;br /&gt;
		pageobj.setCreateOption(&amp;#039;nocreate&amp;#039;);&lt;br /&gt;
		pageobj.setMaxConflictRetries(10);&lt;br /&gt;
		pageobj.save(params.unlinker.workerSuccess, params.unlinker.workerFailure);&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>