<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-Edittools.js</id>
	<title>MediaWiki:Gadget-Edittools.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-Edittools.js"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-Edittools.js&amp;action=history"/>
	<updated>2026-04-10T18:19:10Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=MediaWiki:Gadget-Edittools.js&amp;diff=475171&amp;oldid=prev</id>
		<title>Sware: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-Edittools.js&amp;diff=475171&amp;oldid=prev"/>
		<updated>2025-11-04T17:55: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 17:55, 4 November 2025&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>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=MediaWiki:Gadget-Edittools.js&amp;diff=475170&amp;oldid=prev</id>
		<title>wikt&gt;Erutuon: incorrect change as these elements are created in the loop</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-Edittools.js&amp;diff=475170&amp;oldid=prev"/>
		<updated>2024-01-30T19:15:04Z</updated>

		<summary type="html">&lt;p&gt;incorrect change as these elements are created in the loop&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;
// implicit dependencies: mediawiki.cookie, jquery.textselection&lt;br /&gt;
&lt;br /&gt;
(function charInsertIIFE () {&lt;br /&gt;
&amp;quot;use strict&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
function CharInsertCookieLegacy(key) {&lt;br /&gt;
	this.key = key;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
CharInsertCookieLegacy.prototype = {&lt;br /&gt;
	get: function () {&lt;br /&gt;
		return parseInt(mw.cookie.get(this.key), 10) || 0;&lt;br /&gt;
	},&lt;br /&gt;
	set: function (value) {&lt;br /&gt;
		if (typeof value === &amp;#039;number&amp;#039;)&lt;br /&gt;
			value = value.toString(10);&lt;br /&gt;
		&lt;br /&gt;
		if (!(typeof value === &amp;#039;string&amp;#039; &amp;amp;&amp;amp; !isNaN(parseInt(value, 10))))&lt;br /&gt;
			throw new TypeError(&amp;quot;Expected string or number&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		return mw.cookie.set(this.key, value);&lt;br /&gt;
	},&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
function CharInsertCookie(key) {&lt;br /&gt;
	this.key = key;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
CharInsertCookie.prototype = {&lt;br /&gt;
	get: function () {&lt;br /&gt;
		return mw.cookie.get(this.key);&lt;br /&gt;
	},&lt;br /&gt;
	set: function (value) {&lt;br /&gt;
		if (typeof value !== &amp;#039;string&amp;#039;)&lt;br /&gt;
			throw new TypeError(&amp;quot;Expected string&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		return mw.cookie.set(this.key, value);&lt;br /&gt;
	},&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
var charInsertCookieLegacy = new CharInsertCookieLegacy(&amp;#039;edittoolscharsubset&amp;#039;);&lt;br /&gt;
var charInsertCookie = new CharInsertCookie(&amp;#039;edittoolscharsubsetname&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
/* ===applyCharinserts=== */&lt;br /&gt;
/* handle &amp;lt;span class=&amp;quot;charinsert&amp;quot;&amp;gt; like &amp;lt;charinsert&amp;gt; */&lt;br /&gt;
&lt;br /&gt;
function applyCharinserts() {&lt;br /&gt;
	var textbox = $(&amp;#039;#wpTextbox1&amp;#039;);&lt;br /&gt;
	&lt;br /&gt;
	textbox.encapsulate = function (left, right) {&lt;br /&gt;
		return this.textSelection(&lt;br /&gt;
			&amp;#039;encapsulateSelection&amp;#039;, {&lt;br /&gt;
				pre: left.replace(/^ */, &amp;#039;&amp;#039;)&lt;br /&gt;
					.replace(/\u0640(.)/g, &amp;#039;$1&amp;#039;), // remove ARABIC TATWEEL before Arabic diacritic&lt;br /&gt;
				peri: &amp;#039;&amp;#039;,&lt;br /&gt;
				post: right&lt;br /&gt;
			}&lt;br /&gt;
		);&lt;br /&gt;
	};&lt;br /&gt;
	&lt;br /&gt;
	// Must set insertArgs in the element for which this is an event handler.&lt;br /&gt;
	function clickFunction () {&lt;br /&gt;
		textbox.encapsulate.apply(textbox, this.insertArgs);&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function getInsertArg(string, start, end) {&lt;br /&gt;
		string = string.substring(start, end);&lt;br /&gt;
		return string !== &amp;#039;&amp;#039;&lt;br /&gt;
			? string.replace(/\x22/g, &amp;#039;&amp;amp;quot;&amp;#039;)&lt;br /&gt;
			: string;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function makeInsertArgs(string) {&lt;br /&gt;
		var index = string.indexOf(&amp;#039;+&amp;#039;);&lt;br /&gt;
		if (index === -1)&lt;br /&gt;
			index = string.length;&lt;br /&gt;
		var left = getInsertArg(string, 0, index);&lt;br /&gt;
		var right = getInsertArg(string, index + 1);&lt;br /&gt;
		return [ left, right ];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function makeCharInserter(string) {&lt;br /&gt;
		var charInserter = document.createElement(&amp;#039;a&amp;#039;);&lt;br /&gt;
		charInserter.onclick = clickFunction;&lt;br /&gt;
		charInserter.href = &amp;#039;#&amp;#039;;&lt;br /&gt;
		charInserter.classList.add(&amp;quot;charinserter&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		var insertArgs = makeInsertArgs(string);&lt;br /&gt;
		charInserter.insertArgs = insertArgs.map(function(arg) {&lt;br /&gt;
			return arg&lt;br /&gt;
				// No-break space (&amp;amp;nbsp;) must become an ASCII space in the inserted&lt;br /&gt;
				// text, but it must be displayed as a no-break space so that combining&lt;br /&gt;
				// characters are clickable.&lt;br /&gt;
				.replace(/\xA0/g, &amp;#039; &amp;#039;)&lt;br /&gt;
				// Dotted circle can be used as a seat for diacritics&lt;br /&gt;
				// but shouldn&amp;#039;t be inserted into the text box.&lt;br /&gt;
				.replace(/^\u25CC(.)/, &amp;#039;$1&amp;#039;);&lt;br /&gt;
			&lt;br /&gt;
		});&lt;br /&gt;
		var visibleText = insertArgs.join(&amp;#039;&amp;#039;);&lt;br /&gt;
		charInserter.appendChild(document.createTextNode(visibleText));&lt;br /&gt;
		&lt;br /&gt;
		return charInserter;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function charInsertify(parent) {&lt;br /&gt;
		if (parent.charInsertified)&lt;br /&gt;
			return;&lt;br /&gt;
		&lt;br /&gt;
		parent.charInsertified = true;&lt;br /&gt;
		&lt;br /&gt;
		// Go through all child nodes of parent.&lt;br /&gt;
		for (var childNode = parent.firstChild;&lt;br /&gt;
				childNode !== null;&lt;br /&gt;
				childNode = childNode.nextSibling) {&lt;br /&gt;
			if (childNode.nodeType === 1) { // Element node&lt;br /&gt;
				charInsertify(childNode);&lt;br /&gt;
			} else if (childNode.nodeType === 3) { // Text node&lt;br /&gt;
				// There is a newline when the wikitext has a line break&lt;br /&gt;
				// followed by a character entity reference such as &amp;amp;#x2002;.&lt;br /&gt;
				// Remove the newline because we don&amp;#039;t want to see multiple spaces.&lt;br /&gt;
				childNode.nodeValue = childNode.nodeValue&lt;br /&gt;
					.replace(/^\n+/, &amp;#039;&amp;#039;);&lt;br /&gt;
				var strings = childNode.nodeValue&lt;br /&gt;
					// Split text content on ASCII whitespace characters&lt;br /&gt;
					// and en space (U+2002) character references.&lt;br /&gt;
					.split(/[ \f\n\r\t\v\u2002]+/g)&lt;br /&gt;
					.filter(function(string) { return string !== &amp;#039;&amp;#039;; });&lt;br /&gt;
				&lt;br /&gt;
				var addedNew = false;&lt;br /&gt;
&lt;br /&gt;
				for (var i = 0; i &amp;lt; strings.length; ++i) {&lt;br /&gt;
					if (i &amp;gt; 0)&lt;br /&gt;
						parent.insertBefore(document.createTextNode(&amp;#039; &amp;#039;), childNode);&lt;br /&gt;
					&lt;br /&gt;
					parent.insertBefore(makeCharInserter(strings[i]), childNode);&lt;br /&gt;
					&lt;br /&gt;
					addedNew = true;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				if (addedNew)&lt;br /&gt;
					parent.removeChild(childNode);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	var charInsertSpans = document.querySelectorAll(&amp;#039;#editpage-specialchars .charinsert&amp;#039;);&lt;br /&gt;
	Array.prototype.forEach.call(charInsertSpans, charInsertify);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function makeCharSubsetMenuText(slug) {&lt;br /&gt;
	return decodeURIComponent(slug&lt;br /&gt;
				.replace(/\.([0-9A-F][0-9A-F])/g, &amp;#039;%$1&amp;#039;)&lt;br /&gt;
				.replace(/_/g, &amp;#039;%20&amp;#039;));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ===addCharSubsetMenu=== */&lt;br /&gt;
/* add menu for selecting subsets of secial characters */&lt;br /&gt;
function addCharSubsetMenu() {&lt;br /&gt;
	var edittools = $(&amp;#039;#editpage-specialchars&amp;#039;);&lt;br /&gt;
	if (edittools.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
	var menu = $(&amp;#039;&amp;lt;select&amp;gt;&amp;#039;)&lt;br /&gt;
				.attr(&amp;quot;id&amp;quot;, &amp;#039;charSubsetControl&amp;#039;).css(&amp;quot;display&amp;quot;, &amp;quot;inline&amp;quot;)&lt;br /&gt;
				.on(&amp;quot;change&amp;quot;, function() {&lt;br /&gt;
					chooseCharSubset($(this).val());&lt;br /&gt;
				});&lt;br /&gt;
&lt;br /&gt;
	var sections = edittools.find(&amp;#039;p&amp;#039;);&lt;br /&gt;
	if (sections.length === 0) return;&lt;br /&gt;
	&lt;br /&gt;
	sections.each(function() {&lt;br /&gt;
		var slug = ($(this).attr(&amp;quot;id&amp;quot;) || &amp;#039;&amp;#039;).replace(/^edittools-/, &amp;#039;&amp;#039;);&lt;br /&gt;
		$(&amp;#039;&amp;lt;option&amp;gt;&amp;#039;).text(makeCharSubsetMenuText(slug)).val(slug).appendTo(menu);&lt;br /&gt;
	});&lt;br /&gt;
&lt;br /&gt;
	/* default subset from cookie */&lt;br /&gt;
	var sectionIndex = charInsertCookieLegacy.get();&lt;br /&gt;
	var sectionName = charInsertCookie.get();&lt;br /&gt;
&lt;br /&gt;
	if (!sectionName) {&lt;br /&gt;
		sectionName = menu.children()[sectionIndex].value;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* update dropdown control to value of cookie */&lt;br /&gt;
	menu.val(sectionName);&lt;br /&gt;
&lt;br /&gt;
	/* display the subset indicated by the cookie */&lt;br /&gt;
	chooseCharSubset(sectionName);&lt;br /&gt;
&lt;br /&gt;
	edittools.prepend(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ===chooseCharSubsetMenu=== */&lt;br /&gt;
&lt;br /&gt;
/* select subsection of special characters */&lt;br /&gt;
function chooseCharSubset(sectionSlug) {&lt;br /&gt;
	var sections = $(&amp;#039;#editpage-specialchars&amp;#039;).find(&amp;#039;p&amp;#039;);&lt;br /&gt;
	var idToShow = &amp;#039;edittools-&amp;#039; + sectionSlug;&lt;br /&gt;
	for (var i = 0; i &amp;lt; sections.length; i++) {&lt;br /&gt;
		var style = sections[i].style;&lt;br /&gt;
		style.display = sections[i].id == idToShow ? &amp;#039;inline&amp;#039; : &amp;#039;none&amp;#039;;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	charInsertCookie.set(sectionSlug);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
	var action = mw.config.get(&amp;#039;wgAction&amp;#039;);&lt;br /&gt;
	if (window.testNewEditJs || !(action === &amp;#039;edit&amp;#039; || action === &amp;#039;submit&amp;#039; &lt;br /&gt;
			|| $(&amp;#039;#editpage-specialchars&amp;#039;).length &amp;gt; 0))&lt;br /&gt;
		return;&lt;br /&gt;
	&lt;br /&gt;
	if (!window.doNotUseDefaultEditTools) // [[User:Conrad.Irwin/edittools.js]]&lt;br /&gt;
		addCharSubsetMenu();&lt;br /&gt;
	&lt;br /&gt;
	applyCharinserts();&lt;br /&gt;
	// Provide three arguments to add one category;&lt;br /&gt;
	// provide an array with [{name: categoryName, insertBefore: categoryInsertBefore, html: categoryHtml}]&lt;br /&gt;
	// to add more than one.&lt;br /&gt;
	mw.hook(&amp;#039;enwiktionary.edittools.addCategory&amp;#039;).add(function (categoryName, categoryInsertBefore, categoryHtml) {&lt;br /&gt;
		var categories = (categoryInsertBefore !== undefined)&lt;br /&gt;
			? [{name: categoryName, insertBefore: categoryInsertBefore, html: categoryHtml}]&lt;br /&gt;
			: categoryName;&lt;br /&gt;
		&lt;br /&gt;
		var edittools = $(&amp;#039;#editpage-specialchars&amp;#039;);&lt;br /&gt;
		if (edittools.length === 0) return;&lt;br /&gt;
		var menu = edittools.find(&amp;#039;#charSubsetControl&amp;#039;);&lt;br /&gt;
		if (menu.length === 0) return;&lt;br /&gt;
		&lt;br /&gt;
		for (var i = 0; i &amp;lt; categories.length; i++) {&lt;br /&gt;
			var category = categories[i];&lt;br /&gt;
			var name = category.name,&lt;br /&gt;
				insertBefore = category.insertBefore,&lt;br /&gt;
				html = category.html;&lt;br /&gt;
			name = name.replace(/\s/g, &amp;#039;_&amp;#039;);&lt;br /&gt;
			var selector = insertBefore ? &amp;#039;#charSubsetControl option[value=&amp;quot;&amp;#039; + insertBefore.replace(&amp;#039;&amp;quot;&amp;#039;, &amp;#039;\\&amp;quot;&amp;#039;) + &amp;#039;&amp;quot;]&amp;#039; : null;&lt;br /&gt;
			var option = $(&amp;#039;&amp;lt;option&amp;gt;&amp;#039;).text(makeCharSubsetMenuText(name)).val(name);&lt;br /&gt;
			&lt;br /&gt;
			$(&amp;#039;&amp;lt;p&amp;gt;&amp;#039;).attr(&amp;#039;id&amp;#039;, &amp;#039;edittools-&amp;#039; + name).addClass(&amp;#039;speciallang&amp;#039;).css(&amp;#039;display&amp;#039;, &amp;#039;none&amp;#039;).html(html).appendTo(edittools);&lt;br /&gt;
			if (selector &amp;amp;&amp;amp; menu.find(selector)) {&lt;br /&gt;
				option.insertBefore(selector);&lt;br /&gt;
			} else {&lt;br /&gt;
				option.appendTo(menu);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		applyCharinserts();&lt;br /&gt;
		var cookieVal = charInsertCookie.get();&lt;br /&gt;
		menu.val(cookieVal);&lt;br /&gt;
		chooseCharSubset(cookieVal);&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
// &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>wikt&gt;Erutuon</name></author>
	</entry>
</feed>