<?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-twinkleunlink.js</id>
	<title>MediaWiki:Gadget-twinkleunlink.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-twinkleunlink.js"/>
	<link rel="alternate" type="text/html" href="https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-twinkleunlink.js&amp;action=history"/>
	<updated>2026-05-06T21:53:53Z</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-twinkleunlink.js&amp;diff=8589&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-twinkleunlink.js&amp;diff=8589&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-8588:rev-8589 --&gt;
&lt;/table&gt;</summary>
		<author><name>NottNott</name></author>
	</entry>
	<entry>
		<id>https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-twinkleunlink.js&amp;diff=8588&amp;oldid=prev</id>
		<title>en&gt;Amorymeltzer: Repo at 712686d: Add Morebits.userIsSysop, use everywhere instead of Morebits.userIsInGroup</title>
		<link rel="alternate" type="text/html" href="https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-twinkleunlink.js&amp;diff=8588&amp;oldid=prev"/>
		<updated>2020-03-04T17:42:42Z</updated>

		<summary type="html">&lt;p&gt;Repo at 712686d: Add Morebits.userIsSysop, use everywhere instead of Morebits.userIsInGroup&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;
 *** twinkleunlink.js: Unlink module&lt;br /&gt;
 ****************************************&lt;br /&gt;
 * Mode of invocation:     Tab (&amp;quot;Unlink&amp;quot;)&lt;br /&gt;
 * Active on:              Non-special pages, except Wikipedia:Sandbox&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
Twinkle.unlink = function twinkleunlink() {&lt;br /&gt;
	if (mw.config.get('wgNamespaceNumber') &amp;lt; 0 || mw.config.get('wgPageName') === 'Wikipedia:Sandbox' ||&lt;br /&gt;
		// Restrict to extended confirmed users (see #428)&lt;br /&gt;
		(!Morebits.userIsInGroup('extendedconfirmed') &amp;amp;&amp;amp; !Morebits.userIsSysop)) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	Twinkle.addPortletLink(Twinkle.unlink.callback, 'Unlink', 'tw-unlink', 'Unlink backlinks');&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.unlink.getChecked2 = function twinkleunlinkGetChecked2(nodelist) {&lt;br /&gt;
	if (!(nodelist instanceof NodeList) &amp;amp;&amp;amp; !(nodelist instanceof HTMLCollection)) {&lt;br /&gt;
		return nodelist.checked ? [ nodelist.values ] : [];&lt;br /&gt;
	}&lt;br /&gt;
	var result = [];&lt;br /&gt;
	for (var i = 0; i &amp;lt; nodelist.length; ++i) {&lt;br /&gt;
		if (nodelist[i].checked) {&lt;br /&gt;
			result.push(nodelist[i].values);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return result;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// the parameter is used when invoking unlink from admin speedy&lt;br /&gt;
Twinkle.unlink.callback = function(presetReason) {&lt;br /&gt;
	var Window = new Morebits.simpleWindow(600, 440);&lt;br /&gt;
	Window.setTitle('Unlink backlinks' + (mw.config.get('wgNamespaceNumber') === 6 ? ' and file usages' : ''));&lt;br /&gt;
	Window.setScriptName('Twinkle');&lt;br /&gt;
	Window.addFooterLink('Twinkle help', 'WP:TW/DOC#unlink');&lt;br /&gt;
&lt;br /&gt;
	var form = new Morebits.quickForm(Twinkle.unlink.callback.evaluate);&lt;br /&gt;
&lt;br /&gt;
	// prepend some basic documentation&lt;br /&gt;
	var node1 = Morebits.htmlNode('code', '[[' + Morebits.pageNameNorm + '|link text]]');&lt;br /&gt;
	var node2 = Morebits.htmlNode('code', 'link text');&lt;br /&gt;
	node1.style.fontFamily = node2.style.fontFamily = 'monospace';&lt;br /&gt;
	node1.style.fontStyle = node2.style.fontStyle = 'normal';&lt;br /&gt;
	form.append({&lt;br /&gt;
		type: 'div',&lt;br /&gt;
		style: 'margin-bottom: 0.5em',&lt;br /&gt;
		label: [&lt;br /&gt;
			'This tool allows you to unlink all incoming links (&amp;quot;backlinks&amp;quot;) that point to this page' +&lt;br /&gt;
				(mw.config.get('wgNamespaceNumber') === 6 ? ', and/or hide all inclusions of this file by wrapping them in &amp;lt;!-- --&amp;gt; comment markup' : '') +&lt;br /&gt;
				'. For instance, ',&lt;br /&gt;
			node1,&lt;br /&gt;
			' would become ',&lt;br /&gt;
			node2,&lt;br /&gt;
			'. Use it with caution.'&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;
		value: presetReason ? presetReason : '',&lt;br /&gt;
		size: 60&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
	var query;&lt;br /&gt;
	if (mw.config.get('wgNamespaceNumber') === 6) {  // File:&lt;br /&gt;
		query = {&lt;br /&gt;
			'action': 'query',&lt;br /&gt;
			'list': [ 'backlinks', 'imageusage' ],&lt;br /&gt;
			'bltitle': mw.config.get('wgPageName'),&lt;br /&gt;
			'iutitle': mw.config.get('wgPageName'),&lt;br /&gt;
			'bllimit': 'max', // 500 is max for normal users, 5000 for bots and sysops&lt;br /&gt;
			'iulimit': 'max', // 500 is max for normal users, 5000 for bots and sysops&lt;br /&gt;
			'blnamespace': Twinkle.getPref('unlinkNamespaces'),&lt;br /&gt;
			'iunamespace': Twinkle.getPref('unlinkNamespaces'),&lt;br /&gt;
			'rawcontinue': true&lt;br /&gt;
		};&lt;br /&gt;
	} else {&lt;br /&gt;
		query = {&lt;br /&gt;
			'action': 'query',&lt;br /&gt;
			'list': 'backlinks',&lt;br /&gt;
			'bltitle': mw.config.get('wgPageName'),&lt;br /&gt;
			'blfilterredir': 'nonredirects',&lt;br /&gt;
			'bllimit': 'max', // 500 is max for normal users, 5000 for bots and sysops&lt;br /&gt;
			'blnamespace': Twinkle.getPref('unlinkNamespaces'),&lt;br /&gt;
			'rawcontinue': true&lt;br /&gt;
		};&lt;br /&gt;
	}&lt;br /&gt;
	var wikipedia_api = new Morebits.wiki.api('Grabbing backlinks', query, Twinkle.unlink.callbacks.display.backlinks);&lt;br /&gt;
	wikipedia_api.params = { form: form, Window: Window, image: mw.config.get('wgNamespaceNumber') === 6 };&lt;br /&gt;
	wikipedia_api.post();&lt;br /&gt;
&lt;br /&gt;
	var root = document.createElement('div');&lt;br /&gt;
	root.style.padding = '15px';  // just so it doesn't look broken&lt;br /&gt;
	Morebits.status.init(root);&lt;br /&gt;
	wikipedia_api.statelem.status('loading...');&lt;br /&gt;
	Window.setContent(root);&lt;br /&gt;
	Window.display();&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.unlink.callback.evaluate = function twinkleunlinkCallbackEvaluate(event) {&lt;br /&gt;
	var reason = event.target.reason.value;&lt;br /&gt;
	if (!reason) {&lt;br /&gt;
		alert('You must specify a reason for unlinking.');&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	var backlinks = [], imageusage = [];&lt;br /&gt;
	if (event.target.backlinks) {&lt;br /&gt;
		backlinks = Twinkle.unlink.getChecked2(event.target.backlinks);&lt;br /&gt;
	}&lt;br /&gt;
	if (event.target.imageusage) {&lt;br /&gt;
		imageusage = Twinkle.unlink.getChecked2(event.target.imageusage);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	Morebits.simpleWindow.setButtonsEnabled(false);&lt;br /&gt;
	Morebits.status.init(event.target);&lt;br /&gt;
&lt;br /&gt;
	var pages = Morebits.array.uniq(backlinks.concat(imageusage));&lt;br /&gt;
&lt;br /&gt;
	var unlinker = new Morebits.batchOperation('Unlinking backlinks' + (imageusage ? ' and instances of file usage' : ''));&lt;br /&gt;
	unlinker.setOption('preserveIndividualStatusLines', true);&lt;br /&gt;
	unlinker.setPageList(pages);&lt;br /&gt;
	var params = { reason: reason, unlinker: unlinker };&lt;br /&gt;
	unlinker.run(function(pageName) {&lt;br /&gt;
		var wikipedia_page = new Morebits.wiki.page(pageName, 'Unlinking in article &amp;quot;' + pageName + '&amp;quot;');&lt;br /&gt;
		wikipedia_page.setBotEdit(true);  // unlink considered a floody operation&lt;br /&gt;
		var innerParams = $.extend({}, params);&lt;br /&gt;
		innerParams.doBacklinks = backlinks &amp;amp;&amp;amp; backlinks.indexOf(pageName) !== -1;&lt;br /&gt;
		innerParams.doImageusage = imageusage &amp;amp;&amp;amp; imageusage.indexOf(pageName) !== -1;&lt;br /&gt;
		wikipedia_page.setCallbackParameters(innerParams);&lt;br /&gt;
		wikipedia_page.load(Twinkle.unlink.callbacks.unlinkBacklinks);&lt;br /&gt;
	});&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Twinkle.unlink.callbacks = {&lt;br /&gt;
	display: {&lt;br /&gt;
		backlinks: function twinkleunlinkCallbackDisplayBacklinks(apiobj) {&lt;br /&gt;
			var xmlDoc = apiobj.responseXML;&lt;br /&gt;
			var havecontent = false;&lt;br /&gt;
			var list, namespaces, i;&lt;br /&gt;
&lt;br /&gt;
			if (apiobj.params.image) {&lt;br /&gt;
				var imageusage = $(xmlDoc).find('query imageusage iu');&lt;br /&gt;
				list = [];&lt;br /&gt;
				for (i = 0; i &amp;lt; imageusage.length; ++i) {&lt;br /&gt;
					var usagetitle = imageusage[i].getAttribute('title');&lt;br /&gt;
					list.push({ label: usagetitle, value: usagetitle, checked: true });&lt;br /&gt;
				}&lt;br /&gt;
				if (!list.length) {&lt;br /&gt;
					apiobj.params.form.append({ type: 'div', label: 'No instances of file usage found.' });&lt;br /&gt;
				} else {&lt;br /&gt;
					apiobj.params.form.append({ type: 'header', label: 'File usage' });&lt;br /&gt;
					namespaces = [];&lt;br /&gt;
					$.each(Twinkle.getPref('unlinkNamespaces'), function(k, v) {&lt;br /&gt;
						namespaces.push(v === '0' ? '(Article)' : mw.config.get('wgFormattedNamespaces')[v]);&lt;br /&gt;
					});&lt;br /&gt;
					apiobj.params.form.append({&lt;br /&gt;
						type: 'div',&lt;br /&gt;
						label: 'Selected namespaces: ' + namespaces.join(', '),&lt;br /&gt;
						tooltip: 'You can change this with your Twinkle preferences, at [[WP:TWPREFS]]'&lt;br /&gt;
					});&lt;br /&gt;
					if ($(xmlDoc).find('query-continue').length) {&lt;br /&gt;
						apiobj.params.form.append({&lt;br /&gt;
							type: 'div',&lt;br /&gt;
							label: 'First ' + list.length.toString() + ' file usages shown.'&lt;br /&gt;
						});&lt;br /&gt;
					}&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, 'imageusage')).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, 'imageusage')).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: 'imageusage',&lt;br /&gt;
						list: list&lt;br /&gt;
					});&lt;br /&gt;
					havecontent = true;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			var backlinks = $(xmlDoc).find('query backlinks bl');&lt;br /&gt;
			if (backlinks.length &amp;gt; 0) {&lt;br /&gt;
				list = [];&lt;br /&gt;
				for (i = 0; i &amp;lt; backlinks.length; ++i) {&lt;br /&gt;
					var title = backlinks[i].getAttribute('title');&lt;br /&gt;
					list.push({ label: title, value: title, checked: true });&lt;br /&gt;
				}&lt;br /&gt;
				apiobj.params.form.append({ type: 'header', label: 'Backlinks' });&lt;br /&gt;
				namespaces = [];&lt;br /&gt;
				$.each(Twinkle.getPref('unlinkNamespaces'), function(k, v) {&lt;br /&gt;
					namespaces.push(v === '0' ? '(Article)' : mw.config.get('wgFormattedNamespaces')[v]);&lt;br /&gt;
				});&lt;br /&gt;
				apiobj.params.form.append({&lt;br /&gt;
					type: 'div',&lt;br /&gt;
					label: 'Selected namespaces: ' + namespaces.join(', '),&lt;br /&gt;
					tooltip: 'You can change this with your Twinkle preferences, at [[WP:TWPREFS]]'&lt;br /&gt;
				});&lt;br /&gt;
				if ($(xmlDoc).find('query-continue').length) {&lt;br /&gt;
					apiobj.params.form.append({&lt;br /&gt;
						type: 'div',&lt;br /&gt;
						label: 'First ' + list.length.toString() + ' backlinks shown.'&lt;br /&gt;
					});&lt;br /&gt;
				}&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, 'backlinks')).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, 'backlinks')).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: 'backlinks',&lt;br /&gt;
					list: list&lt;br /&gt;
				});&lt;br /&gt;
				havecontent = true;&lt;br /&gt;
			} else {&lt;br /&gt;
				apiobj.params.form.append({ type: 'div', label: 'No backlinks found.' });&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (havecontent) {&lt;br /&gt;
				apiobj.params.form.append({ type: 'submit' });&lt;br /&gt;
			}&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($(&amp;quot;input[name='imageusage']&amp;quot;, result));&lt;br /&gt;
			Morebits.checkboxShiftClickSupport($(&amp;quot;input[name='backlinks']&amp;quot;, result));&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	unlinkBacklinks: function twinkleunlinkCallbackUnlinkBacklinks(pageobj) {&lt;br /&gt;
		var oldtext = pageobj.getPageText();&lt;br /&gt;
		var params = pageobj.getCallbackParameters();&lt;br /&gt;
		var wikiPage = new Morebits.wikitext.page(oldtext);&lt;br /&gt;
&lt;br /&gt;
		var summaryText = '', warningString = false;&lt;br /&gt;
		var text;&lt;br /&gt;
&lt;br /&gt;
		// remove image usages&lt;br /&gt;
		if (params.doImageusage) {&lt;br /&gt;
			wikiPage.commentOutImage(mw.config.get('wgTitle'), 'Commented out');&lt;br /&gt;
			text = wikiPage.getText();&lt;br /&gt;
			// did we actually make any changes?&lt;br /&gt;
			if (text === oldtext) {&lt;br /&gt;
				warningString = 'file usages';&lt;br /&gt;
			} else {&lt;br /&gt;
				summaryText = 'Commenting out use(s) of file';&lt;br /&gt;
				oldtext = text;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// remove backlinks&lt;br /&gt;
		if (params.doBacklinks) {&lt;br /&gt;
			wikiPage.removeLink(Morebits.pageNameNorm);&lt;br /&gt;
			text = wikiPage.getText();&lt;br /&gt;
			// did we actually make any changes?&lt;br /&gt;
			if (text === oldtext) {&lt;br /&gt;
				warningString = warningString ? 'backlinks or file usages' : 'backlinks';&lt;br /&gt;
			} else {&lt;br /&gt;
				summaryText = (summaryText ? summaryText + ' / ' : '') + 'Removing link(s) to';&lt;br /&gt;
				oldtext = text;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (warningString) {&lt;br /&gt;
			// nothing to do!&lt;br /&gt;
			pageobj.getStatusElement().error(&amp;quot;Didn't find any &amp;quot; + warningString + ' on the page.');&lt;br /&gt;
			params.unlinker.workerFailure(pageobj);&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		pageobj.setPageText(text);&lt;br /&gt;
		pageobj.setEditSummary(summaryText + ' &amp;quot;' + Morebits.pageNameNorm + '&amp;quot;: ' + params.reason + '.' + Twinkle.getPref('summaryAd'));&lt;br /&gt;
		pageobj.setCreateOption('nocreate');&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>