<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://eurovision.jobogamer.xyz/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://eurovision.jobogamer.xyz/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-twinklebatchdelete.js"/>
	<link rel="alternate" type="text/html" href="https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-twinklebatchdelete.js&amp;action=history"/>
	<updated>2026-05-21T19:32:13Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-twinklebatchdelete.js&amp;diff=65&amp;oldid=prev</id>
		<title>Alfie: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-twinklebatchdelete.js&amp;diff=65&amp;oldid=prev"/>
		<updated>2026-03-19T09:58:26Z</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;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 05:58, 19 March 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&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;/table&gt;</summary>
		<author><name>Alfie</name></author>
	</entry>
	<entry>
		<id>https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-twinklebatchdelete.js&amp;diff=64&amp;oldid=prev</id>
		<title>en&gt;SD0001: Repo at cb9119f: Move all non-test source files to a new src directory (#2254); fix TypeError on submitting with blank page list (#2272)</title>
		<link rel="alternate" type="text/html" href="https://eurovision.jobogamer.xyz/index.php?title=MediaWiki:Gadget-twinklebatchdelete.js&amp;diff=64&amp;oldid=prev"/>
		<updated>2026-01-01T16:52:49Z</updated>

		<summary type="html">&lt;p&gt;Repo at cb9119f: Move all non-test source files to a new src directory (#2254); fix TypeError on submitting with blank page list (#2272)&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;
(function() {&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;
let subpagesLoaded;&lt;br /&gt;
&lt;br /&gt;
Twinkle.batchdelete.callback = function twinklebatchdeleteCallback() {&lt;br /&gt;
	subpagesLoaded = false;&lt;br /&gt;
	const 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;
	Window.addFooterLink(&amp;#039;Give feedback&amp;#039;, &amp;#039;WT:TW&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	const 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;
	const query = {&lt;br /&gt;
		action: &amp;#039;query&amp;#039;,&lt;br /&gt;
		prop: &amp;#039;revisions|info|imageinfo&amp;#039;,&lt;br /&gt;
		inprop: &amp;#039;protection&amp;#039;,&lt;br /&gt;
		rvprop: &amp;#039;size|user&amp;#039;,&lt;br /&gt;
		format: &amp;#039;json&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;
			let 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;
			const 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;
	const 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;
	const statelem = new Morebits.Status(&amp;#039;Grabbing list of pages&amp;#039;);&lt;br /&gt;
	const wikipediaApi = new Morebits.wiki.Api(&amp;#039;loading...&amp;#039;, query, ((apiobj) =&amp;gt; {&lt;br /&gt;
		const response = apiobj.getResponse();&lt;br /&gt;
		let pages = (response.query &amp;amp;&amp;amp; response.query.pages) || [];&lt;br /&gt;
		pages = pages.filter((page) =&amp;gt; !page.missing &amp;amp;&amp;amp; page.imagerepository !== &amp;#039;shared&amp;#039;);&lt;br /&gt;
		pages.sort(Twinkle.sortByNamespace);&lt;br /&gt;
		pages.forEach((page) =&amp;gt; {&lt;br /&gt;
			const metadata = [];&lt;br /&gt;
			if (page.redirect) {&lt;br /&gt;
				metadata.push(&amp;#039;redirect&amp;#039;);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			const editProt = page.protection.filter((pr) =&amp;gt; pr.type === &amp;#039;edit&amp;#039; &amp;amp;&amp;amp; pr.level === &amp;#039;sysop&amp;#039;).pop();&lt;br /&gt;
			if (editProt) {&lt;br /&gt;
				metadata.push(&amp;#039;fully protected&amp;#039; +&lt;br /&gt;
				(editProt.expiry === &amp;#039;infinity&amp;#039; ? &amp;#039; indefinitely&amp;#039; : &amp;#039;, expires &amp;#039; + new Morebits.Date(editProt.expiry).calendar(&amp;#039;utc&amp;#039;) + &amp;#039; (UTC)&amp;#039;));&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (page.ns === 6) {&lt;br /&gt;
				metadata.push(&amp;#039;uploader: &amp;#039; + page.imageinfo[0].user);&lt;br /&gt;
				metadata.push(&amp;#039;last edit from: &amp;#039; + page.revisions[0].user);&lt;br /&gt;
			} else {&lt;br /&gt;
				metadata.push(mw.language.convertNumber(page.revisions[0].size) + &amp;#039; bytes&amp;#039;);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			const title = page.title;&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: editProt ? &amp;#039;color:red&amp;#039; : &amp;#039;&amp;#039;&lt;br /&gt;
			};&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
		const 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((_, e) =&amp;gt; {&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((_, e) =&amp;gt; {&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;
			shiftClickSupport: true,&lt;br /&gt;
			list: $.map(Twinkle.batchdelete.pages, (e) =&amp;gt; e)&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;
		Morebits.QuickForm.getElements(result, &amp;#039;pages&amp;#039;).forEach(Twinkle.generateArrowLinks);&lt;br /&gt;
&lt;br /&gt;
	}), statelem);&lt;br /&gt;
&lt;br /&gt;
	wikipediaApi.params = { form: form, Window: Window };&lt;br /&gt;
	wikipediaApi.post();&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;
	const elements = form.elements.pages;&lt;br /&gt;
	if (elements instanceof NodeList) { // if there are multiple pages&lt;br /&gt;
		for (let 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;
		shiftClickSupport: true,&lt;br /&gt;
		list: $.map(Twinkle.batchdelete.pages, (e) =&amp;gt; e)&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;
	const form = e.target.form;&lt;br /&gt;
	let newPageList;&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, (i, el) =&amp;gt; {&lt;br /&gt;
				// Get back the subgroup from subgroupBeforeDeletion, where we saved it&lt;br /&gt;
				if (el.subgroup === null &amp;amp;&amp;amp; el.subgroupBeforeDeletion) {&lt;br /&gt;
					el.subgroup = el.subgroupBeforeDeletion;&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;
			Morebits.QuickForm.getElements(newPageList, &amp;#039;pages&amp;#039;).forEach(Twinkle.generateArrowLinks);&lt;br /&gt;
			Morebits.QuickForm.getElements(newPageList, &amp;#039;pages.subpages&amp;#039;).forEach(Twinkle.generateArrowLinks);&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;
		const 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;
		const pages = $(form.pages).map((i, el) =&amp;gt; el.value).get();&lt;br /&gt;
&lt;br /&gt;
		const subpageLister = new Morebits.BatchOperation();&lt;br /&gt;
		subpageLister.setOption(&amp;#039;chunkSize&amp;#039;, Twinkle.getPref(&amp;#039;batchChunks&amp;#039;));&lt;br /&gt;
		subpageLister.setPageList(pages);&lt;br /&gt;
		subpageLister.run((pageName) =&amp;gt; {&lt;br /&gt;
			const 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].includes(pageTitle.namespace)) {&lt;br /&gt;
				subpageLister.workerSuccess();&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			const wikipediaApi = 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;
				format: &amp;#039;json&amp;#039;&lt;br /&gt;
			}, ((apiobj) =&amp;gt; {&lt;br /&gt;
				const response = apiobj.getResponse();&lt;br /&gt;
				const pages = (response.query &amp;amp;&amp;amp; response.query.pages) || [];&lt;br /&gt;
				const subpageList = [];&lt;br /&gt;
				pages.sort(Twinkle.sortByNamespace);&lt;br /&gt;
				pages.forEach((page) =&amp;gt; {&lt;br /&gt;
					const metadata = [];&lt;br /&gt;
					if (page.redirect) {&lt;br /&gt;
						metadata.push(&amp;#039;redirect&amp;#039;);&lt;br /&gt;
					}&lt;br /&gt;
&lt;br /&gt;
					const editProt = page.protection.filter((pr) =&amp;gt; pr.type === &amp;#039;edit&amp;#039; &amp;amp;&amp;amp; pr.level === &amp;#039;sysop&amp;#039;).pop();&lt;br /&gt;
					if (editProt) {&lt;br /&gt;
						metadata.push(&amp;#039;fully protected&amp;#039; +&lt;br /&gt;
						(editProt.expiry === &amp;#039;infinity&amp;#039; ? &amp;#039; indefinitely&amp;#039; : &amp;#039;, expires &amp;#039; + new Morebits.Date(editProt.expiry).calendar(&amp;#039;utc&amp;#039;) + &amp;#039; (UTC)&amp;#039;));&lt;br /&gt;
					}&lt;br /&gt;
					if (page.ns === 6) {&lt;br /&gt;
						metadata.push(&amp;#039;uploader: &amp;#039; + page.imageinfo[0].user);&lt;br /&gt;
						metadata.push(&amp;#039;last edit from: &amp;#039; + page.revisions[0].user);&lt;br /&gt;
					} else {&lt;br /&gt;
						metadata.push(mw.language.convertNumber(page.revisions[0].size) + &amp;#039; bytes&amp;#039;);&lt;br /&gt;
					}&lt;br /&gt;
&lt;br /&gt;
					const title = page.title;&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: editProt ? &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;
					const pageName = apiobj.params.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;
						shiftClickSupport: true,&lt;br /&gt;
						list: subpageList&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
				subpageLister.workerSuccess();&lt;br /&gt;
			}), null /* statusElement */, (() =&amp;gt; {&lt;br /&gt;
				subpageLister.workerFailure();&lt;br /&gt;
			}));&lt;br /&gt;
			wikipediaApi.params = { pageNameFull: pageName }; // Used in onSuccess()&lt;br /&gt;
			wikipediaApi.post();&lt;br /&gt;
&lt;br /&gt;
		}, () =&amp;gt; {&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;
			Morebits.QuickForm.getElements(newPageList, &amp;#039;pages&amp;#039;).forEach(Twinkle.generateArrowLinks);&lt;br /&gt;
			Morebits.QuickForm.getElements(newPageList, &amp;#039;pages.subpages&amp;#039;).forEach(Twinkle.generateArrowLinks);&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, (i, el) =&amp;gt; {&lt;br /&gt;
			if (el.subgroup) {&lt;br /&gt;
				// Remove subgroup after saving its contents in subgroupBeforeDeletion&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.subgroupBeforeDeletion = 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;
		Morebits.QuickForm.getElements(newPageList, &amp;#039;pages&amp;#039;).forEach(Twinkle.generateArrowLinks);&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;
	const form = event.target;&lt;br /&gt;
&lt;br /&gt;
	const numProtected = $(Morebits.QuickForm.getElements(form, &amp;#039;pages&amp;#039;)).filter((index, element) =&amp;gt; element.checked &amp;amp;&amp;amp; element.nextElementSibling.style.color === &amp;#039;red&amp;#039;).length;&lt;br /&gt;
	if (numProtected &amp;gt; 0 &amp;amp;&amp;amp; !confirm(&amp;#039;You are about to delete &amp;#039; + mw.language.convertNumber(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;
	const input = Morebits.QuickForm.getInputData(form);&lt;br /&gt;
&lt;br /&gt;
	if (!input.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 (!input.pages || input.pages.length === 0) { // undefined if there are no pages linked from the page&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;
	const pageDeleter = new Morebits.BatchOperation(input.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;batchChunks&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;, input.delete_page);&lt;br /&gt;
	pageDeleter.setPageList(input.pages);&lt;br /&gt;
	pageDeleter.run((pageName) =&amp;gt; {&lt;br /&gt;
		const params = {&lt;br /&gt;
			page: pageName,&lt;br /&gt;
			delete_page: input.delete_page,&lt;br /&gt;
			delete_talk: input.delete_talk,&lt;br /&gt;
			delete_redirects: input.delete_redirects,&lt;br /&gt;
			unlink_page: input.unlink_page,&lt;br /&gt;
			unlink_file: input.unlink_file &amp;amp;&amp;amp; new RegExp(&amp;#039;^&amp;#039; + Morebits.namespaceRegex(6) + &amp;#039;:&amp;#039;, &amp;#039;i&amp;#039;).test(pageName),&lt;br /&gt;
			reason: input.reason,&lt;br /&gt;
			pageDeleter: pageDeleter&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		const wikipediaPage = new Morebits.wiki.Page(pageName, &amp;#039;Deleting page &amp;#039; + pageName);&lt;br /&gt;
		wikipediaPage.setCallbackParameters(params);&lt;br /&gt;
		if (input.delete_page) {&lt;br /&gt;
			wikipediaPage.setEditSummary(input.reason);&lt;br /&gt;
			wikipediaPage.setChangeTags(Twinkle.changeTags);&lt;br /&gt;
			wikipediaPage.suppressProtectWarning();&lt;br /&gt;
			wikipediaPage.deletePage(Twinkle.batchdelete.callbacks.doExtras, pageDeleter.workerFailure);&lt;br /&gt;
		} else {&lt;br /&gt;
			Twinkle.batchdelete.callbacks.doExtras(wikipediaPage);&lt;br /&gt;
		}&lt;br /&gt;
	}, () =&amp;gt; {&lt;br /&gt;
		if (input.delete_subpages &amp;amp;&amp;amp; input.subpages) {&lt;br /&gt;
			const subpageDeleter = new Morebits.BatchOperation(&amp;#039;Deleting subpages&amp;#039;);&lt;br /&gt;
			subpageDeleter.setOption(&amp;#039;chunkSize&amp;#039;, Twinkle.getPref(&amp;#039;batchChunks&amp;#039;));&lt;br /&gt;
			subpageDeleter.setOption(&amp;#039;preserveIndividualStatusLines&amp;#039;, true);&lt;br /&gt;
			subpageDeleter.setPageList(input.subpages);&lt;br /&gt;
			subpageDeleter.run((pageName) =&amp;gt; {&lt;br /&gt;
				const params = {&lt;br /&gt;
					page: pageName,&lt;br /&gt;
					delete_page: true,&lt;br /&gt;
					delete_talk: input.delete_subpage_talks,&lt;br /&gt;
					delete_redirects: input.delete_subpage_redirects,&lt;br /&gt;
					unlink_page: input.unlink_subpages,&lt;br /&gt;
					unlink_file: false,&lt;br /&gt;
					reason: input.reason,&lt;br /&gt;
					pageDeleter: subpageDeleter&lt;br /&gt;
				};&lt;br /&gt;
&lt;br /&gt;
				const wikipediaPage = new Morebits.wiki.Page(pageName, &amp;#039;Deleting subpage &amp;#039; + pageName);&lt;br /&gt;
				wikipediaPage.setCallbackParameters(params);&lt;br /&gt;
				wikipediaPage.setEditSummary(input.reason);&lt;br /&gt;
				wikipediaPage.setChangeTags(Twinkle.changeTags);&lt;br /&gt;
				wikipediaPage.suppressProtectWarning();&lt;br /&gt;
				wikipediaPage.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;
		const 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;
		let query, wikipediaApi;&lt;br /&gt;
&lt;br /&gt;
		if (params.unlink_page) {&lt;br /&gt;
			Twinkle.batchdelete.unlinkCache = {};&lt;br /&gt;
			query = {&lt;br /&gt;
				action: &amp;#039;query&amp;#039;,&lt;br /&gt;
				list: &amp;#039;backlinks&amp;#039;,&lt;br /&gt;
				blfilterredir: &amp;#039;nonredirects&amp;#039;,&lt;br /&gt;
				blnamespace: [0, 100], // main space and portal space only&lt;br /&gt;
				bltitle: params.page,&lt;br /&gt;
				bllimit: &amp;#039;max&amp;#039;, // 500 is max for normal users, 5000 for bots and sysops&lt;br /&gt;
				format: &amp;#039;json&amp;#039;&lt;br /&gt;
			};&lt;br /&gt;
			wikipediaApi = new Morebits.wiki.Api(&amp;#039;Grabbing backlinks&amp;#039;, query, Twinkle.batchdelete.callbacks.unlinkBacklinksMain);&lt;br /&gt;
			wikipediaApi.params = params;&lt;br /&gt;
			wikipediaApi.post();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (params.unlink_file) {&lt;br /&gt;
			query = {&lt;br /&gt;
				action: &amp;#039;query&amp;#039;,&lt;br /&gt;
				list: &amp;#039;imageusage&amp;#039;,&lt;br /&gt;
				iutitle: params.page,&lt;br /&gt;
				iulimit: &amp;#039;max&amp;#039;, // 500 is max for normal users, 5000 for bots and sysops&lt;br /&gt;
				format: &amp;#039;json&amp;#039;&lt;br /&gt;
			};&lt;br /&gt;
			wikipediaApi = new Morebits.wiki.Api(&amp;#039;Grabbing file links&amp;#039;, query, Twinkle.batchdelete.callbacks.unlinkImageInstancesMain);&lt;br /&gt;
			wikipediaApi.params = params;&lt;br /&gt;
			wikipediaApi.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;
					action: &amp;#039;query&amp;#039;,&lt;br /&gt;
					titles: params.page,&lt;br /&gt;
					prop: &amp;#039;redirects&amp;#039;,&lt;br /&gt;
					rdlimit: &amp;#039;max&amp;#039;, // 500 is max for normal users, 5000 for bots and sysops&lt;br /&gt;
					format: &amp;#039;json&amp;#039;&lt;br /&gt;
				};&lt;br /&gt;
				wikipediaApi = new Morebits.wiki.Api(&amp;#039;Grabbing redirects&amp;#039;, query, Twinkle.batchdelete.callbacks.deleteRedirectsMain);&lt;br /&gt;
				wikipediaApi.params = params;&lt;br /&gt;
				wikipediaApi.post();&lt;br /&gt;
			}&lt;br /&gt;
			if (params.delete_talk) {&lt;br /&gt;
				const 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;
						action: &amp;#039;query&amp;#039;,&lt;br /&gt;
						titles: pageTitle.toText(),&lt;br /&gt;
						format: &amp;#039;json&amp;#039;&lt;br /&gt;
					};&lt;br /&gt;
					wikipediaApi = new Morebits.wiki.Api(&amp;#039;Checking whether talk page exists&amp;#039;, query, Twinkle.batchdelete.callbacks.deleteTalk);&lt;br /&gt;
					wikipediaApi.params = params;&lt;br /&gt;
					wikipediaApi.params.talkPage = pageTitle.toText();&lt;br /&gt;
					wikipediaApi.post();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	deleteRedirectsMain: function(apiobj) {&lt;br /&gt;
		const response = apiobj.getResponse();&lt;br /&gt;
		let pages = response.query.pages[0].redirects || [];&lt;br /&gt;
		pages = pages.map((redirect) =&amp;gt; redirect.title);&lt;br /&gt;
		if (!pages.length) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		const 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;batchChunks&amp;#039;));&lt;br /&gt;
		redirectDeleter.setPageList(pages);&lt;br /&gt;
		redirectDeleter.run((pageName) =&amp;gt; {&lt;br /&gt;
			const wikipediaPage = new Morebits.wiki.Page(pageName, &amp;#039;Deleting &amp;#039; + pageName);&lt;br /&gt;
			wikipediaPage.setEditSummary(&amp;#039;[[WP:CSD#G8|G8]]: Redirect to deleted page [[&amp;#039; + apiobj.params.page + &amp;#039;]]&amp;#039;);&lt;br /&gt;
			wikipediaPage.setChangeTags(Twinkle.changeTags);&lt;br /&gt;
			wikipediaPage.deletePage(redirectDeleter.workerSuccess, redirectDeleter.workerFailure);&lt;br /&gt;
		});&lt;br /&gt;
	},&lt;br /&gt;
	deleteTalk: function(apiobj) {&lt;br /&gt;
		const response = apiobj.getResponse();&lt;br /&gt;
&lt;br /&gt;
		// no talk page; forget about it&lt;br /&gt;
		if (response.query.pages[0].missing) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		const page = new Morebits.wiki.Page(apiobj.params.talkPage, &amp;#039;Deleting talk page of page &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;#039; + apiobj.params.page + &amp;#039;]]&amp;#039;);&lt;br /&gt;
		page.setChangeTags(Twinkle.changeTags);&lt;br /&gt;
		page.deletePage();&lt;br /&gt;
	},&lt;br /&gt;
	unlinkBacklinksMain: function(apiobj) {&lt;br /&gt;
		const response = apiobj.getResponse();&lt;br /&gt;
		let pages = response.query.backlinks || [];&lt;br /&gt;
		pages = pages.map((page) =&amp;gt; page.title);&lt;br /&gt;
		if (!pages.length) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		const 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;batchChunks&amp;#039;));&lt;br /&gt;
		unlinker.setPageList(pages);&lt;br /&gt;
		unlinker.run((pageName) =&amp;gt; {&lt;br /&gt;
			const wikipediaPage = new Morebits.wiki.Page(pageName, &amp;#039;Unlinking on &amp;#039; + pageName);&lt;br /&gt;
			const params = $.extend({}, apiobj.params);&lt;br /&gt;
			params.title = pageName;&lt;br /&gt;
			params.unlinker = unlinker;&lt;br /&gt;
			wikipediaPage.setCallbackParameters(params);&lt;br /&gt;
			wikipediaPage.load(Twinkle.batchdelete.callbacks.unlinkBacklinks);&lt;br /&gt;
		});&lt;br /&gt;
	},&lt;br /&gt;
	unlinkBacklinks: function(pageobj) {&lt;br /&gt;
		const 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;
		let 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;
		const oldText = text;&lt;br /&gt;
		const wikiPage = new Morebits.wikitext.Page(text);&lt;br /&gt;
		text = wikiPage.removeLink(params.page).getText();&lt;br /&gt;
&lt;br /&gt;
		Twinkle.batchdelete.unlinkCache[params.title] = text;&lt;br /&gt;
		if (text === oldText) {&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);&lt;br /&gt;
		pageobj.setChangeTags(Twinkle.changeTags);&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;
		const response = apiobj.getResponse();&lt;br /&gt;
		let pages = response.query.imageusage || [];&lt;br /&gt;
		pages = pages.map((page) =&amp;gt; page.title);&lt;br /&gt;
		if (!pages.length) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		const 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;batchChunks&amp;#039;));&lt;br /&gt;
		unlinker.setPageList(pages);&lt;br /&gt;
		unlinker.run((pageName) =&amp;gt; {&lt;br /&gt;
			const wikipediaPage = new Morebits.wiki.Page(pageName, &amp;#039;Removing file usages on &amp;#039; + pageName);&lt;br /&gt;
			const params = $.extend({}, apiobj.params);&lt;br /&gt;
			params.title = pageName;&lt;br /&gt;
			params.unlinker = unlinker;&lt;br /&gt;
			wikipediaPage.setCallbackParameters(params);&lt;br /&gt;
			wikipediaPage.load(Twinkle.batchdelete.callbacks.unlinkImageInstances);&lt;br /&gt;
		});&lt;br /&gt;
	},&lt;br /&gt;
	unlinkImageInstances: function(pageobj) {&lt;br /&gt;
		const 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;
		const image = params.page.replace(new RegExp(&amp;#039;^&amp;#039; + Morebits.namespaceRegex(6) + &amp;#039;:&amp;#039;), &amp;#039;&amp;#039;);&lt;br /&gt;
		let 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;
		const oldText = text;&lt;br /&gt;
		const wikiPage = new Morebits.wikitext.Page(text);&lt;br /&gt;
		text = wikiPage.commentOutImage(image, &amp;#039;Commented out because image was deleted&amp;#039;).getText();&lt;br /&gt;
&lt;br /&gt;
		Twinkle.batchdelete.unlinkCache[params.title] = text;&lt;br /&gt;
		if (text === oldText) {&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;);&lt;br /&gt;
		pageobj.setChangeTags(Twinkle.changeTags);&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;
&lt;br /&gt;
Twinkle.addInitCallback(Twinkle.batchdelete, &amp;#039;batchdelete&amp;#039;);&lt;br /&gt;
}());&lt;br /&gt;
&lt;br /&gt;
// &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>en&gt;SD0001</name></author>
	</entry>
</feed>