<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
	<id>https://arolstar52-zhtest.hf.space/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-ToolsRedirect.js</id>
	<title>MediaWiki:Gadget-ToolsRedirect.js - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://arolstar52-zhtest.hf.space/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-ToolsRedirect.js"/>
	<link rel="alternate" type="text/html" href="https://arolstar52-zhtest.hf.space/index.php?title=MediaWiki:Gadget-ToolsRedirect.js&amp;action=history"/>
	<updated>2026-07-18T20:01:23Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://arolstar52-zhtest.hf.space/index.php?title=MediaWiki:Gadget-ToolsRedirect.js&amp;diff=696713&amp;oldid=prev</id>
		<title>imported&gt;Diskdance：​使用HanAssist</title>
		<link rel="alternate" type="text/html" href="https://arolstar52-zhtest.hf.space/index.php?title=MediaWiki:Gadget-ToolsRedirect.js&amp;diff=696713&amp;oldid=prev"/>
		<updated>2025-07-31T05:28:32Z</updated>

		<summary type="html">&lt;p&gt;使用HanAssist&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;// &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;use strict&amp;#039;;&lt;br /&gt;
(function ($) {&lt;br /&gt;
	const { conv } = require(&amp;#039;ext.gadget.HanAssist&amp;#039;);&lt;br /&gt;
	&lt;br /&gt;
	var nsNumber = mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;),&lt;br /&gt;
		origPageName = mw.config.get(&amp;#039;wgPageName&amp;#039;),&lt;br /&gt;
		scriptPath = mw.config.get(&amp;#039;wgScriptPath&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	var SUFFIX_APPEND = 0,&lt;br /&gt;
		SUFFIX_REPLACE = 1,&lt;br /&gt;
		SUFFIX_SETDEFAULT = 2,&lt;br /&gt;
		isCategory = nsNumber === 14;&lt;br /&gt;
&lt;br /&gt;
	if (nsNumber === -1) {&lt;br /&gt;
		var chainNoop = function () { return this; };&lt;br /&gt;
		var noop = function () {};&lt;br /&gt;
		mw.toolsRedirect = {&lt;br /&gt;
			SUFFIX_APPEND,&lt;br /&gt;
			SUFFIX_REPLACE,&lt;br /&gt;
			SUFFIX_SETDEFAULT,&lt;br /&gt;
			findRedirectCallback: chainNoop,&lt;br /&gt;
			findRedirectBySelector: chainNoop,&lt;br /&gt;
			setRedirectTextSuffix: noop&lt;br /&gt;
		};&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	var _TR,&lt;br /&gt;
		_findRedirectCallbacks = [],&lt;br /&gt;
		_pageWithRedirectTextSuffix = {},&lt;br /&gt;
		_redirectExcludes = {};&lt;br /&gt;
	var _nsCanonPrefix = origPageName.split(&amp;#039;:&amp;#039;)[0] + &amp;#039;:&amp;#039;,&lt;br /&gt;
		_nsPrefixPattern = $.map(mw.config.get(&amp;#039;wgNamespaceIds&amp;#039;), function (nsid, text) {&lt;br /&gt;
			return nsid === nsNumber ? text : null;&lt;br /&gt;
		}).join(&amp;#039;|&amp;#039;);&lt;br /&gt;
	_nsPrefixPattern = new RegExp(&amp;#039;^(&amp;#039; + _nsPrefixPattern + &amp;#039;):&amp;#039;, &amp;#039;i&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	if (nsNumber === 0) {&lt;br /&gt;
		// articles&lt;br /&gt;
		_nsCanonPrefix = &amp;#039;&amp;#039;;&lt;br /&gt;
		_nsPrefixPattern = /^/;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function fixNamespace(title) {&lt;br /&gt;
		if (nsNumber === 0) {&lt;br /&gt;
			// do nothing if it&amp;#039;s articles&lt;br /&gt;
			return title;&lt;br /&gt;
		} else if (_nsPrefixPattern.test(title)) {&lt;br /&gt;
			// canonize the namespace&lt;br /&gt;
			return title.replace(_nsPrefixPattern, _nsCanonPrefix);&lt;br /&gt;
		} else {&lt;br /&gt;
			// don&amp;#039;t have a namespace&lt;br /&gt;
			return _nsCanonPrefix + title;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	mw.toolsRedirect = {&lt;br /&gt;
		SUFFIX_APPEND: SUFFIX_APPEND,&lt;br /&gt;
		SUFFIX_REPLACE: SUFFIX_REPLACE,&lt;br /&gt;
		SUFFIX_SETDEFAULT: SUFFIX_SETDEFAULT,&lt;br /&gt;
&lt;br /&gt;
		findRedirectCallback: function (callback) {&lt;br /&gt;
			/* Add new custom callback for finding new&lt;br /&gt;
			 * potential redirect titles.&lt;br /&gt;
			 *&lt;br /&gt;
			 * @param {function} callback( pagename, $content, titles ) -&amp;gt; title list&lt;br /&gt;
			 */&lt;br /&gt;
			if (arguments.length === 1) {&lt;br /&gt;
				_findRedirectCallbacks.push(callback);&lt;br /&gt;
			} else {&lt;br /&gt;
				$.merge(_findRedirectCallbacks, arguments);&lt;br /&gt;
			}&lt;br /&gt;
			return this;&lt;br /&gt;
		},&lt;br /&gt;
&lt;br /&gt;
		findRedirectBySelector: function (selector) {&lt;br /&gt;
			/* A shortcut to add CSS selectors as rule to find new potential&lt;br /&gt;
			 * redirect titles.&lt;br /&gt;
			 *&lt;br /&gt;
			 * @param {string} selector&lt;br /&gt;
			 */&lt;br /&gt;
			_findRedirectCallbacks.push(function () {&lt;br /&gt;
				return $(selector).map(function () {&lt;br /&gt;
					var title = $(this).text();&lt;br /&gt;
					return title || null;&lt;br /&gt;
				});&lt;br /&gt;
			});&lt;br /&gt;
			return this;&lt;br /&gt;
		},&lt;br /&gt;
&lt;br /&gt;
		setRedirectTextSuffix: function (title, suffix, flag) {&lt;br /&gt;
			var flag_set = false,&lt;br /&gt;
				flag_append = false;&lt;br /&gt;
			flag = flag || SUFFIX_APPEND; // default append&lt;br /&gt;
			flag_set = flag === SUFFIX_REPLACE;&lt;br /&gt;
			title = fixNamespace(title);&lt;br /&gt;
			if (title in _pageWithRedirectTextSuffix) {&lt;br /&gt;
				flag_append = flag === SUFFIX_APPEND;&lt;br /&gt;
			} else {&lt;br /&gt;
				// if not exist, every flag can set&lt;br /&gt;
				flag_set = true;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (flag_set) {&lt;br /&gt;
				_pageWithRedirectTextSuffix[title] = suffix;&lt;br /&gt;
			} else if (flag_append) {&lt;br /&gt;
				_pageWithRedirectTextSuffix[title] = _pageWithRedirectTextSuffix[title] + suffix;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	_TR = {&lt;br /&gt;
		msg: null,&lt;br /&gt;
		tabselem: null,&lt;br /&gt;
		tagselem: null,&lt;br /&gt;
		variants: [&amp;#039;zh-hans&amp;#039;, &amp;#039;zh-hant&amp;#039;, &amp;#039;zh-cn&amp;#039;, &amp;#039;zh-hk&amp;#039;, &amp;#039;zh-mo&amp;#039;, &amp;#039;zh-sg&amp;#039;, &amp;#039;zh-tw&amp;#039;],&lt;br /&gt;
		init: function () {&lt;br /&gt;
			if (!this.msg) {&lt;br /&gt;
				return;&lt;br /&gt;
			} // not setup correctly&lt;br /&gt;
			var self = this,&lt;br /&gt;
				btn = $(mw.util.addPortletLink(&amp;#039;p-views&amp;#039;, &amp;#039;#&amp;#039;, this.msg.btntitle, &amp;#039;ca-redirect&amp;#039;, this.msg.btndesc, null, &amp;#039;#ca-watch&amp;#039;)).addClass(&amp;#039;collapsible&amp;#039;).css(&amp;#039;cursor&amp;#039;, &amp;#039;pointer&amp;#039;);&lt;br /&gt;
			btn.click(function (evt) {&lt;br /&gt;
				evt.preventDefault();&lt;br /&gt;
				self.dialog();&lt;br /&gt;
			});&lt;br /&gt;
			mw.config.get(&amp;#039;skin&amp;#039;) === &amp;#039;vector-2022&amp;#039; ? $(&amp;#039;#p-cactions ul&amp;#039;).append(btn) : $(&amp;#039;li#ca-history&amp;#039;).after(btn);&lt;br /&gt;
		},&lt;br /&gt;
		dialog: function () {&lt;br /&gt;
			var dlg = $(&amp;#039;&amp;lt;div class=&amp;quot;dialog-redirect&amp;quot; title=&amp;quot;&amp;#039; + this.msg.dlgtitle + &amp;#039;&amp;quot;&amp;gt;&amp;#039;).dialog({&lt;br /&gt;
				bgiframe: true,&lt;br /&gt;
				resizable: false,&lt;br /&gt;
				modal: true,&lt;br /&gt;
				width: 600,&lt;br /&gt;
			});&lt;br /&gt;
			this.tabselem = $(&amp;#039;&amp;lt;div class=&amp;quot;tab-redirect&amp;quot;&amp;gt;&amp;#039;).appendTo(dlg);&lt;br /&gt;
			this.tagselem = $(&amp;#039;&amp;lt;ul&amp;gt;&amp;#039;).appendTo(this.tabselem);&lt;br /&gt;
			this.addTabs();&lt;br /&gt;
			this.tabselem.tabs();&lt;br /&gt;
		},&lt;br /&gt;
		addTabs: function () {&lt;br /&gt;
			for (var kname in this.tabs) {&lt;br /&gt;
				if (this.tabs[kname] === null) {&lt;br /&gt;
					this.tabs[kname] = this[&amp;#039;_initTab&amp;#039; + kname[0].charAt(0).toUpperCase() + kname.slice(1)]();&lt;br /&gt;
				}&lt;br /&gt;
				var tab = this.tabs[kname];&lt;br /&gt;
				this.tagselem.append(tab.tag);&lt;br /&gt;
				this.tabselem.append(tab.cont);&lt;br /&gt;
			}&lt;br /&gt;
			// default tab, autoload when dialog initiate&lt;br /&gt;
			this.loadView();&lt;br /&gt;
		},&lt;br /&gt;
		createTab: function (tabname, tabtitle, onClick) {&lt;br /&gt;
			var self = this,&lt;br /&gt;
				tag = $(&amp;#039;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#tab-&amp;#039; + tabname + &amp;#039;&amp;quot;&amp;gt;&amp;#039; + tabtitle + &amp;#039;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;#039;),&lt;br /&gt;
				cont = $(&amp;#039;&amp;lt;div id=&amp;quot;tab-&amp;#039; + tabname + &amp;#039;&amp;quot;/&amp;gt;&amp;#039;);&lt;br /&gt;
			$(&amp;#039;a&amp;#039;, tag).on(&amp;#039;click&amp;#039;, function () {&lt;br /&gt;
				onClick.call(self);&lt;br /&gt;
			});&lt;br /&gt;
			return {tag: tag, cont: cont, loaded: false};&lt;br /&gt;
		},&lt;br /&gt;
		_initTabView: function () {&lt;br /&gt;
			return this.createTab(&amp;#039;view&amp;#039;, this.msg.tabviewtitle, this.loadView);&lt;br /&gt;
		},&lt;br /&gt;
		_initTabCreate: function () {&lt;br /&gt;
			return this.createTab(&amp;#039;create&amp;#039;, this.msg.tabcreatetitle, this.loadCreate);&lt;br /&gt;
		},&lt;br /&gt;
		tabs: {&lt;br /&gt;
			view: null,&lt;br /&gt;
			create: null,&lt;br /&gt;
		},&lt;br /&gt;
		fix: function (pagenames) {&lt;br /&gt;
			var self = this;&lt;br /&gt;
			$(&amp;#039;p.desc&amp;#039;, this.tabs.view.cont).text(this.msg.fixloading);&lt;br /&gt;
			$(&amp;#039;p[class!=desc]&amp;#039;, this.tabs.view.cont).remove();&lt;br /&gt;
			this.loading(this.tabs.view.cont);&lt;br /&gt;
			this.bulkEditByRegex(pagenames, / \[\[(.*?)\]\]/, (_, oldRedirectTarget) =&amp;gt; {&lt;br /&gt;
				let newRedirectTarget = origPageName;&lt;br /&gt;
				if (oldRedirectTarget.includes(&amp;#039;#&amp;#039;)) {&lt;br /&gt;
					// 嘗試複製章節&lt;br /&gt;
					const oldRedirectTitle = mw.Title.newFromText(oldRedirectTarget);&lt;br /&gt;
					if (oldRedirectTitle &amp;amp;&amp;amp; oldRedirectTitle.fragment) {&lt;br /&gt;
						newRedirectTarget += `#${oldRedirectTitle.fragment}`;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				return ` [[${newRedirectTarget}]]`;&lt;br /&gt;
			}, this.msg.fixsummary).done(function () {&lt;br /&gt;
				// delay load before the asynchronous tasks on server finished&lt;br /&gt;
				setTimeout(function () {&lt;br /&gt;
					self.loaded(self.tabs.view.cont);&lt;br /&gt;
					self.loadView(true);&lt;br /&gt;
				}, 3000);&lt;br /&gt;
			});&lt;br /&gt;
		},&lt;br /&gt;
		create: function (pagenames) {&lt;br /&gt;
			var self = this;&lt;br /&gt;
			$(&amp;#039;p.desc&amp;#039;, this.tabs.create.cont).text(this.msg.createloading);&lt;br /&gt;
			$(&amp;#039;p[class!=desc]&amp;#039;, this.tabs.create.cont).remove();&lt;br /&gt;
			this.loading(this.tabs.create.cont);&lt;br /&gt;
			this.bulkEdit(pagenames, this.msg.createtext.replace(&amp;#039;$1&amp;#039;, origPageName), this.msg.createsummary.replace(&amp;#039;$1&amp;#039;, origPageName)).done(function () {&lt;br /&gt;
				// delay load before the asynchronous tasks on server finished&lt;br /&gt;
				setTimeout(function () {&lt;br /&gt;
					self.loaded(self.tabs.create.cont);&lt;br /&gt;
					self.tabs.view.loaded = false;&lt;br /&gt;
					self.loadCreate(true);&lt;br /&gt;
				}, 500);&lt;br /&gt;
			});&lt;br /&gt;
		},&lt;br /&gt;
		addRedirectTextSuffix: function (title, text) {&lt;br /&gt;
			if (title in _pageWithRedirectTextSuffix) {&lt;br /&gt;
				text = text + _pageWithRedirectTextSuffix[title];&lt;br /&gt;
			}&lt;br /&gt;
			return text;&lt;br /&gt;
		},&lt;br /&gt;
		bulkEdit: function (titles, text, summary) {&lt;br /&gt;
			var self = this;&lt;br /&gt;
			titles = titles.filter(function (v, i, arr) {&lt;br /&gt;
				return arr.indexOf(v) === i;&lt;br /&gt;
			});&lt;br /&gt;
			titles = titles.join(&amp;#039;|&amp;#039;);&lt;br /&gt;
			return $.ajax(this.buildQuery({action: &amp;#039;query&amp;#039;, prop: &amp;#039;info&amp;#039;, titles: titles, meta: &amp;#039;tokens&amp;#039;})).then(function (data) {&lt;br /&gt;
				var deferreds = [];&lt;br /&gt;
				$.each(data.query.pages, function (idx, page) {&lt;br /&gt;
					deferreds.push(&lt;br /&gt;
						$.ajax(&lt;br /&gt;
							self.buildQuery({&lt;br /&gt;
								action: &amp;#039;edit&amp;#039;,&lt;br /&gt;
								title: page.title,&lt;br /&gt;
								token: data.query.tokens.csrftoken,&lt;br /&gt;
								text: self.addRedirectTextSuffix(page.title, text),&lt;br /&gt;
								summary: summary,&lt;br /&gt;
								tags: &amp;#039;ToolsRedirect&amp;#039;,&lt;br /&gt;
							})&lt;br /&gt;
						)&lt;br /&gt;
					);&lt;br /&gt;
				});&lt;br /&gt;
				return $.when.apply($, deferreds);&lt;br /&gt;
			});&lt;br /&gt;
		},&lt;br /&gt;
		bulkEditByRegex: function (titles, r, t, summary) {&lt;br /&gt;
			var self = this;&lt;br /&gt;
			titles = titles.filter(function (v, i, arr) {&lt;br /&gt;
				return arr.indexOf(v) === i;&lt;br /&gt;
			});&lt;br /&gt;
			titles = titles.join(&amp;#039;|&amp;#039;);&lt;br /&gt;
			return $.ajax(this.buildQuery({ action: &amp;#039;query&amp;#039;, prop: &amp;#039;revisions&amp;#039;, titles: titles, rvprop: &amp;#039;content&amp;#039;, meta: &amp;#039;tokens&amp;#039; })).then(function (data) {&lt;br /&gt;
				var deferreds = [];&lt;br /&gt;
				$.each(data.query.pages, function (idx, page) {&lt;br /&gt;
					var content = page.revisions[0][&amp;#039;*&amp;#039;];&lt;br /&gt;
					var newContent = content.replace(r, t);&lt;br /&gt;
					deferreds.push(&lt;br /&gt;
						$.ajax(&lt;br /&gt;
							self.buildQuery({&lt;br /&gt;
								action: &amp;#039;edit&amp;#039;,&lt;br /&gt;
								title: page.title,&lt;br /&gt;
								token: data.query.tokens.csrftoken,&lt;br /&gt;
								text: newContent,&lt;br /&gt;
								summary: summary,&lt;br /&gt;
								tags: &amp;#039;ToolsRedirect&amp;#039;,&lt;br /&gt;
								basetimestamp: page.revisions[0].timestamp,&lt;br /&gt;
							})&lt;br /&gt;
						)&lt;br /&gt;
					);&lt;br /&gt;
				});&lt;br /&gt;
				return $.when.apply($, deferreds);&lt;br /&gt;
			});&lt;br /&gt;
		},&lt;br /&gt;
		loadTabCont: function (tabname, callback, reload) {&lt;br /&gt;
			var self = this,&lt;br /&gt;
				tab = this.tabs[tabname];&lt;br /&gt;
			if (reload) {&lt;br /&gt;
				tab.loaded = false;&lt;br /&gt;
			}&lt;br /&gt;
			if (!tab.loaded) {&lt;br /&gt;
				tab.cont.html(&amp;#039;&amp;#039;);&lt;br /&gt;
				var $desc = $(&amp;#039;&amp;lt;p class=&amp;quot;desc&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;desc-text&amp;quot;&amp;gt;&amp;#039; + this.msg.rediloading + &amp;#039;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&amp;#039;).appendTo(tab.cont),&lt;br /&gt;
					$text = $desc.find(&amp;#039;&amp;gt; .desc-text&amp;#039;);&lt;br /&gt;
				callback&lt;br /&gt;
					.apply(this)&lt;br /&gt;
					.done(function () {&lt;br /&gt;
						$text.text(self.msg[&amp;#039;tab&amp;#039; + tabname + &amp;#039;desc&amp;#039;]);&lt;br /&gt;
					})&lt;br /&gt;
					.fail(function () {&lt;br /&gt;
						$text.text(self.msg[&amp;#039;tab&amp;#039; + tabname + &amp;#039;notfound&amp;#039;]);&lt;br /&gt;
					})&lt;br /&gt;
					.always(function () {&lt;br /&gt;
						self.addMethods($desc, [&lt;br /&gt;
							{&lt;br /&gt;
								href: &amp;#039;#refresh&amp;#039;,&lt;br /&gt;
								title: self.msg.refresh,&lt;br /&gt;
								click: function (evt) {&lt;br /&gt;
									evt.preventDefault();&lt;br /&gt;
									self.loadTabCont(tabname, callback, true);&lt;br /&gt;
								},&lt;br /&gt;
							},&lt;br /&gt;
						]);&lt;br /&gt;
					});&lt;br /&gt;
				tab.loaded = true;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		loading: function (container) {&lt;br /&gt;
			if (container.prop(&amp;#039;tagName&amp;#039;).toLowerCase() === &amp;#039;span&amp;#039;) {&lt;br /&gt;
				container.addClass(&amp;#039;mw-ajax-loader&amp;#039;);&lt;br /&gt;
			} else if ($(&amp;#039;span.mw-ajax-loader&amp;#039;, container).length === 0) {&lt;br /&gt;
				$(&amp;#039;&amp;lt;span class=&amp;quot;mw-ajax-loader&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;#039;).appendTo(container);&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		loaded: function (container) {&lt;br /&gt;
			if (container.prop(&amp;#039;tagName&amp;#039;).toLowerCase() === &amp;#039;span&amp;#039;) {&lt;br /&gt;
				container.removeClass(&amp;#039;mw-ajax-loader&amp;#039;);&lt;br /&gt;
			} else {&lt;br /&gt;
				$(&amp;#039;span.mw-ajax-loader&amp;#039;, container).remove();&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		selectAll: function (cont) {&lt;br /&gt;
			$(&amp;#039;input[type=checkbox]:not(:disabled)&amp;#039;, cont).prop(&amp;#039;checked&amp;#039;, true);&lt;br /&gt;
		},&lt;br /&gt;
		selectInverse: function (cont) {&lt;br /&gt;
			$(&amp;#039;input[type=checkbox]:not(:disabled)&amp;#039;, cont).each(function () {&lt;br /&gt;
				var e = $(this);&lt;br /&gt;
				e.prop(&amp;#039;checked&amp;#039;, !e.prop(&amp;#039;checked&amp;#039;));&lt;br /&gt;
			});&lt;br /&gt;
		},&lt;br /&gt;
		selectAction: function (cont, cb) {&lt;br /&gt;
			var pagenames = [];&lt;br /&gt;
			$(&amp;#039;input[type=checkbox]:checked&amp;#039;, cont).each(function () {&lt;br /&gt;
				pagenames.push($(this).data(&amp;#039;page-title&amp;#039;));&lt;br /&gt;
			});&lt;br /&gt;
			if (pagenames.length) {&lt;br /&gt;
				cb.call(this, pagenames);&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		clickAction: function (cont, cb) {&lt;br /&gt;
			var pagename = $(&amp;#039;input[type=&amp;quot;checkbox&amp;quot;]&amp;#039;, cont).data(&amp;#039;page-title&amp;#039;);&lt;br /&gt;
			cb.call(this, [pagename]);&lt;br /&gt;
		},&lt;br /&gt;
		buildLink: function (attr) {&lt;br /&gt;
			var a = $(&amp;#039;&amp;lt;a href=&amp;quot;&amp;#039; + attr.href + &amp;#039;&amp;quot; title=&amp;quot;&amp;#039; + attr.title + &amp;#039;&amp;quot; target=&amp;quot;blank&amp;quot;&amp;gt;&amp;#039; + attr.title + &amp;#039;&amp;lt;/a&amp;gt;&amp;#039;);&lt;br /&gt;
			if (attr.click) {&lt;br /&gt;
				a.on(&amp;#039;click&amp;#039;, attr.click);&lt;br /&gt;
			}&lt;br /&gt;
			if (attr.classname) {&lt;br /&gt;
				a.addClass(attr.classname);&lt;br /&gt;
			}&lt;br /&gt;
			return $(&amp;#039;&amp;lt;span class=&amp;quot;tools-redirect_link&amp;quot;&amp;gt;&amp;#039;).append(a);&lt;br /&gt;
		},&lt;br /&gt;
		addMethods: function ($parent, methods) {&lt;br /&gt;
			var self = this,&lt;br /&gt;
				$container = $parent.find(&amp;#039;&amp;gt; .tools-redirect_methods&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
			function methodExist(method) {&lt;br /&gt;
				return $container.find(&amp;#039;a[href=&amp;#039; + JSON.stringify(method.href) + &amp;#039;]&amp;#039;).length &amp;gt; 0;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if ($container.length === 0) {&lt;br /&gt;
				$container = $(&amp;#039;&amp;lt;span class=&amp;quot;tools-redirect_methods&amp;quot;&amp;gt;&amp;#039;).appendTo($parent);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			$.each(methods, function (idx, method) {&lt;br /&gt;
				if (!methodExist(method)) {&lt;br /&gt;
					self.buildLink(method).appendTo($container);&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		},&lt;br /&gt;
		buildSelection: function (main, metd, mt, dsab) {&lt;br /&gt;
			var cont = $(&amp;#039;&amp;lt;span&amp;gt;&amp;#039;),&lt;br /&gt;
				sele = $(&amp;#039;&amp;lt;input type=&amp;quot;checkbox&amp;quot;/&amp;gt;&amp;#039;).appendTo(cont);&lt;br /&gt;
			this.buildLink(main).appendTo(cont);&lt;br /&gt;
			this.addMethods(cont, metd);&lt;br /&gt;
			sele.data(&amp;#039;page-title&amp;#039;, mt);&lt;br /&gt;
			if (dsab) {&lt;br /&gt;
				sele.attr(&amp;#039;disabled&amp;#039;, true);&lt;br /&gt;
			}&lt;br /&gt;
			return cont;&lt;br /&gt;
		},&lt;br /&gt;
		loadView: function (reload) {&lt;br /&gt;
			var $container = this.tabs.view.cont;&lt;br /&gt;
			this.loadTabCont(&lt;br /&gt;
				&amp;#039;view&amp;#039;,&lt;br /&gt;
				function () {&lt;br /&gt;
					return this.loadRedirect(origPageName, $container, 0);&lt;br /&gt;
				},&lt;br /&gt;
				reload&lt;br /&gt;
			);&lt;br /&gt;
		},&lt;br /&gt;
		loadCreate: function (reload) {&lt;br /&gt;
			this.loadTabCont(&lt;br /&gt;
				&amp;#039;create&amp;#039;,&lt;br /&gt;
				function () {&lt;br /&gt;
					return this.findRedirect(origPageName);&lt;br /&gt;
				},&lt;br /&gt;
				reload&lt;br /&gt;
			);&lt;br /&gt;
		},&lt;br /&gt;
		loadRedirect: function (pagename, container, deep, loaded) {&lt;br /&gt;
			this.loading(container);&lt;br /&gt;
			var self = this,&lt;br /&gt;
				deferObj = $.Deferred(),&lt;br /&gt;
				top = deep ? $(&amp;#039;&amp;lt;dl&amp;gt;&amp;#039;).appendTo(container) : container;&lt;br /&gt;
&lt;br /&gt;
			if (!loaded) {&lt;br /&gt;
				loaded = {};&lt;br /&gt;
				loaded[pagename] = true;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			function onClickFix(evt) {&lt;br /&gt;
				/* jshint validthis: true */&lt;br /&gt;
				var entry = $(this).parents(&amp;#039;dd, p&amp;#039;).first();&lt;br /&gt;
				evt.preventDefault();&lt;br /&gt;
				self.clickAction(entry, self.fix);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			$.ajax(this.buildQuery({action: &amp;#039;query&amp;#039;, prop: &amp;#039;redirects&amp;#039;, titles: pagename, rdlimit: &amp;#039;max&amp;#039;})).done(function (data) {&lt;br /&gt;
				self.loaded(container);&lt;br /&gt;
				var has_redirect = false,&lt;br /&gt;
					desc = $(&amp;#039;p.desc&amp;#039;, self.tabs.view.cont),&lt;br /&gt;
					maximumRedirectDepth = mw.config.get(&amp;#039;toolsRedirectMaximumRedirectDepth&amp;#039;, 10);&lt;br /&gt;
&lt;br /&gt;
				$.each(data.query.pages, function (_, page) {&lt;br /&gt;
					if (!(&amp;#039;redirects&amp;#039; in page)) {&lt;br /&gt;
						return;&lt;br /&gt;
					}&lt;br /&gt;
					$.each(page.redirects, function (_, rdpage) {&lt;br /&gt;
						var $container,&lt;br /&gt;
							isCycleRedirect,&lt;br /&gt;
							rdtitle = rdpage.title,&lt;br /&gt;
							ultitle = rdtitle.replace(/ /g, &amp;#039;_&amp;#039;),&lt;br /&gt;
							baseuri = scriptPath + &amp;#039;/index.php?title=&amp;#039; + encodeURIComponent(ultitle),&lt;br /&gt;
							entry = (deep ? $(&amp;#039;&amp;lt;dd&amp;gt;&amp;#039;) : $(&amp;#039;&amp;lt;p&amp;gt;&amp;#039;)).appendTo(top),&lt;br /&gt;
							methods = [&lt;br /&gt;
								{&lt;br /&gt;
									href: baseuri + &amp;#039;&amp;amp;action=edit&amp;#039;,&lt;br /&gt;
									title: self.msg.rediedit,&lt;br /&gt;
								},&lt;br /&gt;
							];&lt;br /&gt;
						isCycleRedirect = rdtitle in loaded;&lt;br /&gt;
						loaded[rdtitle] = true;&lt;br /&gt;
						if (!isCycleRedirect &amp;amp;&amp;amp; deep) {&lt;br /&gt;
							methods.push({&lt;br /&gt;
								href: &amp;#039;#fix-redirect&amp;#039;,&lt;br /&gt;
								title: self.msg.tabviewfix,&lt;br /&gt;
								click: onClickFix,&lt;br /&gt;
							});&lt;br /&gt;
						}&lt;br /&gt;
						$container = self.buildSelection({href: baseuri + &amp;#039;&amp;amp;redirect=no&amp;#039;, title: rdtitle}, methods, ultitle, !deep).appendTo(entry);&lt;br /&gt;
						if (isCycleRedirect) {&lt;br /&gt;
							$container.append(&amp;#039;&amp;lt;span class=&amp;quot;error&amp;quot;&amp;gt;&amp;#039; + self.msg.errcycleredirect + &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;);&lt;br /&gt;
						} else if (deep &amp;lt; maximumRedirectDepth) {&lt;br /&gt;
							deferObj.done(function () {&lt;br /&gt;
								return self.loadRedirect(rdtitle, entry, deep + 1, loaded);&lt;br /&gt;
							});&lt;br /&gt;
						}&lt;br /&gt;
						has_redirect = true;&lt;br /&gt;
					});&lt;br /&gt;
				});&lt;br /&gt;
&lt;br /&gt;
				if (has_redirect &amp;amp;&amp;amp; deep === 1) {&lt;br /&gt;
					self.addMethods(desc, [&lt;br /&gt;
						{&lt;br /&gt;
							href: &amp;#039;#select-all&amp;#039;,&lt;br /&gt;
							title: self.msg.selectall,&lt;br /&gt;
							click: function (evt) {&lt;br /&gt;
								evt.preventDefault();&lt;br /&gt;
								self.selectAll(self.tabs.view.cont);&lt;br /&gt;
							},&lt;br /&gt;
						},&lt;br /&gt;
						{&lt;br /&gt;
							href: &amp;#039;#select-inverse&amp;#039;,&lt;br /&gt;
							title: self.msg.selectinverse,&lt;br /&gt;
							click: function (evt) {&lt;br /&gt;
								evt.preventDefault();&lt;br /&gt;
								self.selectInverse(self.tabs.view.cont);&lt;br /&gt;
							},&lt;br /&gt;
						},&lt;br /&gt;
						{&lt;br /&gt;
							href: &amp;#039;#fix-selected&amp;#039;,&lt;br /&gt;
							title: self.msg.tabviewfix,&lt;br /&gt;
							click: function (evt) {&lt;br /&gt;
								evt.preventDefault();&lt;br /&gt;
								self.selectAction(self.tabs.view.cont, self.fix);&lt;br /&gt;
							},&lt;br /&gt;
						},&lt;br /&gt;
					]);&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				if (has_redirect) {&lt;br /&gt;
					deferObj.resolveWith(self);&lt;br /&gt;
				} else {&lt;br /&gt;
					deferObj.rejectWith(self);&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
			return deferObj.promise();&lt;br /&gt;
		},&lt;br /&gt;
		findVariants: function (pagename, titles) {&lt;br /&gt;
			var self = this,&lt;br /&gt;
				suffixReg = /^.+?( \(.+?\))$/,&lt;br /&gt;
				retTitles = [],&lt;br /&gt;
				deferreds = [],&lt;br /&gt;
				simpAndTrad = {&amp;#039;zh-hans&amp;#039;: true, &amp;#039;zh-hant&amp;#039;: true};&lt;br /&gt;
			$.each(this.variants, function (_, variant) {&lt;br /&gt;
				var xhr = $.ajax(&lt;br /&gt;
					self.buildQuery({&lt;br /&gt;
						action: &amp;#039;parse&amp;#039;,&lt;br /&gt;
						page: pagename,&lt;br /&gt;
						prop: &amp;#039;displaytitle&amp;#039;,&lt;br /&gt;
						variant: variant,&lt;br /&gt;
					})&lt;br /&gt;
				).then(function (data) {&lt;br /&gt;
					var title = fixNamespace(data.parse.displaytitle);&lt;br /&gt;
					if (variant in simpAndTrad) {&lt;br /&gt;
						mw.toolsRedirect.setRedirectTextSuffix(title, &amp;#039;\n{{簡繁重定向}}&amp;#039;, SUFFIX_APPEND);&lt;br /&gt;
					}&lt;br /&gt;
					return title;&lt;br /&gt;
				});&lt;br /&gt;
				if (isCategory) {&lt;br /&gt;
					xhr = xhr.then(function (origTitle) {&lt;br /&gt;
						return $.ajax(&lt;br /&gt;
							self.buildQuery({&lt;br /&gt;
								action: &amp;#039;parse&amp;#039;,&lt;br /&gt;
								text: pagename,&lt;br /&gt;
								prop: &amp;#039;text&amp;#039;,&lt;br /&gt;
								variant: variant,&lt;br /&gt;
							})&lt;br /&gt;
						).then(function (data) {&lt;br /&gt;
							var tmpTitle = $(data.parse.text[&amp;#039;*&amp;#039;])&lt;br /&gt;
								.text()&lt;br /&gt;
								.replace(/(^\s*|\s*$)/g, &amp;#039;&amp;#039;);&lt;br /&gt;
							// should not create redirect categories&lt;br /&gt;
							// if the conversion is already in global table,&lt;br /&gt;
							// or it will mess up a lot&lt;br /&gt;
							_redirectExcludes[tmpTitle] = true;&lt;br /&gt;
							return origTitle;&lt;br /&gt;
						});&lt;br /&gt;
					});&lt;br /&gt;
				}&lt;br /&gt;
				deferreds.push(xhr);&lt;br /&gt;
			});&lt;br /&gt;
			return $.when.apply($, deferreds).then(function () {&lt;br /&gt;
				var suffixes = [];&lt;br /&gt;
				$.each(arguments, function () {&lt;br /&gt;
					var suffix,&lt;br /&gt;
						title = this;&lt;br /&gt;
					// find title suffix,&lt;br /&gt;
					// for example &amp;quot; (济南市)&amp;quot; to &amp;quot;市中区 (济南市)&amp;quot;&lt;br /&gt;
					suffix = suffixReg.exec(title);&lt;br /&gt;
					if (suffix &amp;amp;&amp;amp; suffix.length === 2) {&lt;br /&gt;
						suffix = suffix[1];&lt;br /&gt;
					} else {&lt;br /&gt;
						suffix = &amp;#039;&amp;#039;;&lt;br /&gt;
					}&lt;br /&gt;
					retTitles.push(title);&lt;br /&gt;
					suffixes.push(suffix);&lt;br /&gt;
				});&lt;br /&gt;
				// append suffixes&lt;br /&gt;
				$.each($.uniqueSort(suffixes), function (_, suffix) {&lt;br /&gt;
					$.merge(&lt;br /&gt;
						retTitles,&lt;br /&gt;
						$.map(titles, function (title) {&lt;br /&gt;
							title = fixNamespace(title);&lt;br /&gt;
							return suffixReg.test(title) ? title : title + suffix;&lt;br /&gt;
						})&lt;br /&gt;
					);&lt;br /&gt;
				});&lt;br /&gt;
				return self.findNotExists($.uniqueSort(retTitles));&lt;br /&gt;
			});&lt;br /&gt;
		},&lt;br /&gt;
&lt;br /&gt;
		findNotExists: function (titles) {&lt;br /&gt;
			var self = this,&lt;br /&gt;
				deferreds = [],&lt;br /&gt;
				alltitles = [],&lt;br /&gt;
				excludes = [&amp;#039;用字模式&amp;#039;];&lt;br /&gt;
			titles = titles.join(&amp;#039;|&amp;#039;);&lt;br /&gt;
			$.each([&amp;#039;zh-hans&amp;#039;, &amp;#039;zh-hant&amp;#039;], function (idx, variant) {&lt;br /&gt;
				deferreds.push($.ajax(self.buildQuery({action: &amp;#039;parse&amp;#039;, text: titles, prop: &amp;#039;text&amp;#039;, variant: variant})));&lt;br /&gt;
			});&lt;br /&gt;
			return $.when.apply($, deferreds).then(function () {&lt;br /&gt;
				$.each(arguments, function () {&lt;br /&gt;
					alltitles = alltitles.concat(&lt;br /&gt;
						$(this[0].parse.text[&amp;#039;*&amp;#039;])&lt;br /&gt;
							.text()&lt;br /&gt;
							.replace(/(^\s*|\s*$)/g, &amp;#039;&amp;#039;)&lt;br /&gt;
							.split(&amp;#039;|&amp;#039;)&lt;br /&gt;
					);&lt;br /&gt;
				});&lt;br /&gt;
				alltitles = alltitles.filter(function (v, i, arr) {&lt;br /&gt;
					return arr.indexOf(v) === i;&lt;br /&gt;
				});&lt;br /&gt;
				alltitles = alltitles.join(&amp;#039;|&amp;#039;);&lt;br /&gt;
				return $.ajax(&lt;br /&gt;
					self.buildQuery({&lt;br /&gt;
						action: &amp;#039;query&amp;#039;,&lt;br /&gt;
						prop: &amp;#039;info&amp;#039;,&lt;br /&gt;
						titles: alltitles,&lt;br /&gt;
					})&lt;br /&gt;
				).then(function (data) {&lt;br /&gt;
					titles = [];&lt;br /&gt;
					$.each(data.query.pages, function (pageid, page) {&lt;br /&gt;
						var title = page.title;&lt;br /&gt;
						if (pageid &amp;lt; 0 &amp;amp;&amp;amp; excludes.indexOf(title) === -1) {&lt;br /&gt;
							if (title in _redirectExcludes) {&lt;br /&gt;
								// exclude special titles&lt;br /&gt;
								return;&lt;br /&gt;
							}&lt;br /&gt;
							titles.push(title);&lt;br /&gt;
							if (isCategory) {&lt;br /&gt;
								var target = origPageName.replace(/^Category:/, &amp;#039;&amp;#039;);&lt;br /&gt;
								mw.toolsRedirect.setRedirectTextSuffix(title, &amp;#039;\n{{分类重定向|$1}}&amp;#039;.replace(&amp;#039;$1&amp;#039;, target));&lt;br /&gt;
							}&lt;br /&gt;
							// only set default suffix&lt;br /&gt;
							mw.toolsRedirect.setRedirectTextSuffix(title, &amp;#039;\n{{別名重定向}}&amp;#039;, SUFFIX_SETDEFAULT);&lt;br /&gt;
						}&lt;br /&gt;
					});&lt;br /&gt;
					return titles;&lt;br /&gt;
				});&lt;br /&gt;
			});&lt;br /&gt;
		},&lt;br /&gt;
&lt;br /&gt;
		findRedirect: function (pagename) {&lt;br /&gt;
			var self = this,&lt;br /&gt;
				titles = [],&lt;br /&gt;
				frcDeferreds = [],&lt;br /&gt;
				container = this.tabs.create.cont,&lt;br /&gt;
				$content = $(&amp;#039;#mw-content-text &amp;gt; div.mw-parser-output&amp;#039;),&lt;br /&gt;
				deferObj = $.Deferred();&lt;br /&gt;
			this.loading(container);&lt;br /&gt;
			$.each(_findRedirectCallbacks, function (_, callback) {&lt;br /&gt;
				var ret = callback(pagename, $content, titles);&lt;br /&gt;
				if (typeof ret === &amp;#039;string&amp;#039;) {&lt;br /&gt;
					titles.push(ret);&lt;br /&gt;
				} else if (&amp;#039;done&amp;#039; in ret) {&lt;br /&gt;
					// is Deferred&lt;br /&gt;
					frcDeferreds.push(ret);&lt;br /&gt;
				} else {&lt;br /&gt;
					$.merge(titles, ret);&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
			// remove all empty titles&lt;br /&gt;
			titles = $.map(titles, function (title) {&lt;br /&gt;
				return title || null;&lt;br /&gt;
			});&lt;br /&gt;
			function onClickCreate(evt) {&lt;br /&gt;
				/* jshint validthis: true */&lt;br /&gt;
				var entry = $(this).parents(&amp;#039;p:first&amp;#039;);&lt;br /&gt;
				evt.preventDefault();&lt;br /&gt;
				self.clickAction(entry, self.create);&lt;br /&gt;
			}&lt;br /&gt;
			// handles the deferred callbacks&lt;br /&gt;
			$.when&lt;br /&gt;
				.apply($, frcDeferreds)&lt;br /&gt;
				.then(function () {&lt;br /&gt;
					$.each(arguments, function (_, ret) {&lt;br /&gt;
						if (typeof ret === &amp;#039;string&amp;#039;) {&lt;br /&gt;
							titles.push(ret);&lt;br /&gt;
						} else {&lt;br /&gt;
							$.merge(titles, ret);&lt;br /&gt;
						}&lt;br /&gt;
					});&lt;br /&gt;
					return self.findVariants(pagename, titles);&lt;br /&gt;
				})&lt;br /&gt;
				.done(function (titles) {&lt;br /&gt;
					// build HTML&lt;br /&gt;
					self.loaded(container);&lt;br /&gt;
					$.each(titles, function (_, title) {&lt;br /&gt;
						var ultitle = title.replace(&amp;#039; &amp;#039;, &amp;#039;_&amp;#039;),&lt;br /&gt;
							baseuri = scriptPath + &amp;#039;/index.php?title=&amp;#039; + encodeURIComponent(ultitle),&lt;br /&gt;
							entry = $(&amp;#039;&amp;lt;p&amp;gt;&amp;#039;).appendTo(container);&lt;br /&gt;
						self.buildSelection(&lt;br /&gt;
							{&lt;br /&gt;
								href: baseuri + &amp;#039;&amp;amp;action=edit&amp;amp;redlink=1&amp;#039;,&lt;br /&gt;
								title: title,&lt;br /&gt;
								classname: &amp;#039;new&amp;#039;,&lt;br /&gt;
							},&lt;br /&gt;
							[&lt;br /&gt;
								{&lt;br /&gt;
									href: &amp;#039;#create-redirect&amp;#039;,&lt;br /&gt;
									title: self.msg.tabcreatetitle,&lt;br /&gt;
									click: onClickCreate,&lt;br /&gt;
								},&lt;br /&gt;
							],&lt;br /&gt;
							ultitle,&lt;br /&gt;
							false&lt;br /&gt;
						).appendTo(entry);&lt;br /&gt;
					});&lt;br /&gt;
					var desc = $(&amp;#039;p.desc&amp;#039;, container);&lt;br /&gt;
					if (titles.length &amp;gt; 0) {&lt;br /&gt;
						self.addMethods(desc, [&lt;br /&gt;
							{&lt;br /&gt;
								href: &amp;#039;#select-all&amp;#039;,&lt;br /&gt;
								title: self.msg.selectall,&lt;br /&gt;
								click: function (evt) {&lt;br /&gt;
									evt.preventDefault();&lt;br /&gt;
									self.selectAll(container);&lt;br /&gt;
								},&lt;br /&gt;
							},&lt;br /&gt;
							{&lt;br /&gt;
								href: &amp;#039;#select-inverse&amp;#039;,&lt;br /&gt;
								title: self.msg.selectinverse,&lt;br /&gt;
								click: function (evt) {&lt;br /&gt;
									evt.preventDefault();&lt;br /&gt;
									self.selectInverse(container);&lt;br /&gt;
								},&lt;br /&gt;
							},&lt;br /&gt;
							{&lt;br /&gt;
								href: &amp;#039;#create-selected&amp;#039;,&lt;br /&gt;
								title: self.msg.tabcreatetitle,&lt;br /&gt;
								click: function (evt) {&lt;br /&gt;
									evt.preventDefault();&lt;br /&gt;
									self.selectAction(container, self.create);&lt;br /&gt;
								},&lt;br /&gt;
							},&lt;br /&gt;
						]);&lt;br /&gt;
						deferObj.resolveWith(self, [titles]);&lt;br /&gt;
					} else {&lt;br /&gt;
						deferObj.rejectWith(self, [titles]);&lt;br /&gt;
					}&lt;br /&gt;
				});&lt;br /&gt;
			return deferObj.promise();&lt;br /&gt;
		},&lt;br /&gt;
		buildQuery: function (data) {&lt;br /&gt;
			var query = {url: scriptPath + &amp;#039;/api.php&amp;#039;, dataType: &amp;#039;json&amp;#039;, type: &amp;#039;POST&amp;#039;};&lt;br /&gt;
			query.data = data;&lt;br /&gt;
			query.data.format = &amp;#039;json&amp;#039;;&lt;br /&gt;
			return query;&lt;br /&gt;
		},&lt;br /&gt;
	};&lt;br /&gt;
	$.when(mw.loader.getScript(&amp;#039;/w/index.php?title=MediaWiki:Gadget-ToolsRedirect-msg-&amp;#039; + conv({ hans: &amp;#039;zh-hans&amp;#039;, hant: &amp;#039;zh-hant&amp;#039; }) + &amp;#039;.js&amp;amp;action=raw&amp;amp;ctype=text/javascript&amp;#039;), $.ready).done(function () {&lt;br /&gt;
		_TR.msg = window.tools_redirect_msg;&lt;br /&gt;
		_TR.init();&lt;br /&gt;
	});&lt;br /&gt;
})(jQuery);&lt;br /&gt;
&lt;br /&gt;
// &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>imported&gt;Diskdance</name></author>
	</entry>
</feed>