<?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-WiktGadgetPrefs.js</id>
	<title>MediaWiki:Gadget-WiktGadgetPrefs.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-WiktGadgetPrefs.js"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-WiktGadgetPrefs.js&amp;action=history"/>
	<updated>2026-04-05T08:11:32Z</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-WiktGadgetPrefs.js&amp;diff=475195&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-WiktGadgetPrefs.js&amp;diff=475195&amp;oldid=prev"/>
		<updated>2025-11-04T17:55:40Z</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-WiktGadgetPrefs.js&amp;diff=475194&amp;oldid=prev</id>
		<title>wikt&gt;Ioaxxere: docs should encourage good style</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-WiktGadgetPrefs.js&amp;diff=475194&amp;oldid=prev"/>
		<updated>2025-09-14T16:29:49Z</updated>

		<summary type="html">&lt;p&gt;docs should encourage good style&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/* global mw */&lt;br /&gt;
// &amp;lt;nowiki&amp;gt;&lt;br /&gt;
/*jshint shadow:true, undef:true, latedef:true, unused:true, esversion:3 */&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * WiktGadgetPrefs -- developed by [[wikt:en:User:Surjection]]&lt;br /&gt;
 *&lt;br /&gt;
 * ***********************************************************************&lt;br /&gt;
 * Documentation for gadget authors:&lt;br /&gt;
 * Example usage (remember to add ext.gadget.WiktGadgetPrefs as a dependency):&lt;br /&gt;
&lt;br /&gt;
	const preferences = mw.wiktGadgetPrefs.get(&amp;quot;gadgetfoobar&amp;quot;, &lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;label&amp;quot;: {&lt;br /&gt;
				&amp;quot;en&amp;quot;: &amp;quot;Foobar Gadget&amp;quot;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;frobulate&amp;quot;: {&lt;br /&gt;
				&amp;quot;type&amp;quot;: &amp;quot;boolean&amp;quot;,&lt;br /&gt;
				&amp;quot;default&amp;quot;: false,&lt;br /&gt;
				&amp;quot;label&amp;quot;: {&lt;br /&gt;
					&amp;quot;en&amp;quot;: &amp;quot;Whether this gadget should frobulate&amp;quot;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	);&lt;br /&gt;
	const shouldFrobulate = preferences.frobulate;&lt;br /&gt;
&lt;br /&gt;
    // strenum example&lt;br /&gt;
	const preferences = mw.wiktGadgetPrefs.get(&amp;quot;gadgetfoobar&amp;quot;, &lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;label&amp;quot;: {&lt;br /&gt;
				&amp;quot;en&amp;quot;: &amp;quot;Foobar Gadget&amp;quot;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;frobulate&amp;quot;: {&lt;br /&gt;
				&amp;quot;type&amp;quot;: &amp;quot;strenum&amp;quot;,&lt;br /&gt;
				&amp;quot;default&amp;quot;: &amp;quot;yes&amp;quot;,&lt;br /&gt;
				&amp;quot;label&amp;quot;: {&lt;br /&gt;
					&amp;quot;en&amp;quot;: &amp;quot;Whether this gadget should frobulate&amp;quot;&lt;br /&gt;
				},&lt;br /&gt;
				&amp;quot;choices&amp;quot;: [&lt;br /&gt;
					&amp;quot;yes&amp;quot;,&lt;br /&gt;
					&amp;quot;no&amp;quot;,&lt;br /&gt;
					&amp;quot;maybe&amp;quot;&lt;br /&gt;
				],&lt;br /&gt;
				&amp;quot;choiceLabels&amp;quot;: {&lt;br /&gt;
					&amp;quot;en&amp;quot;: {&lt;br /&gt;
						&amp;quot;yes&amp;quot;: &amp;quot;Yes!&amp;quot;,&lt;br /&gt;
						&amp;quot;no&amp;quot;: &amp;quot;No!!&amp;quot;,&lt;br /&gt;
						&amp;quot;maybe&amp;quot;: &amp;quot;Maybe?&amp;quot;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	);&lt;br /&gt;
	const shouldFrobulate = preferences.frobulate;&lt;br /&gt;
 ***********************************************************************&lt;br /&gt;
 * &lt;br /&gt;
 * Dependencies needed: mw.user, user.options&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
(function() {&lt;br /&gt;
	&amp;quot;use strict&amp;quot;;&lt;br /&gt;
	/**&lt;br /&gt;
	 * @typedef WiktGadgetOptions&lt;br /&gt;
	 * - Represents gadget options.&lt;br /&gt;
	 * @property {{[languageCode: string]: string}} [label]&lt;br /&gt;
	 * - The label to display on the preferences page for this&lt;br /&gt;
	 *   gadget/namespace. The language code should be a MediaWiki&lt;br /&gt;
	 *   language code, e.g. &amp;quot;en&amp;quot; for English.&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @typedef WiktGadgetPreference&lt;br /&gt;
	 * - Represents a single preference.&lt;br /&gt;
	 * @property {{&amp;quot;boolean&amp;quot;|&amp;quot;integer&amp;quot;|&amp;quot;string&amp;quot;|&amp;quot;strenum&amp;quot;|&amp;quot;object&amp;quot;}} type&lt;br /&gt;
	 * - Must be one of the following:&lt;br /&gt;
	 * - &amp;quot;boolean&amp;quot; for boolean values, either true or false.&lt;br /&gt;
	 * - &amp;quot;integer&amp;quot; for an integer value.&lt;br /&gt;
	 * - &amp;quot;string&amp;quot; for a string value.&lt;br /&gt;
	 * - &amp;quot;strenum&amp;quot; for a string value that must be one of the options.&lt;br /&gt;
	 * - &amp;quot;object&amp;quot; for an arbitrary JSON value, including null.&lt;br /&gt;
	 *   No type checks are done.&lt;br /&gt;
	 * @property {any} default&lt;br /&gt;
	 * - The default value for this preference if missing, or if&lt;br /&gt;
	 *   the value is invalid.&lt;br /&gt;
	 * - The developer is responsible for ensuring that this value is&lt;br /&gt;
	 *   given, and that it meets the preconditions defined below.&lt;br /&gt;
	 * @property {string[]} [choices]&lt;br /&gt;
	 * - If the type is &amp;quot;strenum&amp;quot;, then this must be an array of&lt;br /&gt;
	 *   allowed options. If the value is not in this list, the default&lt;br /&gt;
	 *   value will be returned.&lt;br /&gt;
	 * @property {number} [minimum]&lt;br /&gt;
	 * - If the type is &amp;quot;integer&amp;quot;, this is the minimum allowed value.&lt;br /&gt;
	 * @property {number} [maximum]&lt;br /&gt;
	 * - If the type is &amp;quot;integer&amp;quot;, this is the maximum allowed value.&lt;br /&gt;
	 * @property {number} [maximumLength]&lt;br /&gt;
	 * - If the type is &amp;quot;string&amp;quot;, this is the maximum allowed length.&lt;br /&gt;
	 * @property {{[languageCode: string]: string}} [label]&lt;br /&gt;
	 * - The label to display on the preferences page for this&lt;br /&gt;
	 *   preference. The language code should be a MediaWiki&lt;br /&gt;
	 *   language code, e.g. &amp;quot;en&amp;quot; for English.&lt;br /&gt;
	 * @property {{[languageCode: string]: {[choice: string]: string}}} [choiceLabels]&lt;br /&gt;
	 * - The label to display on the preferences page for the choices&lt;br /&gt;
	 *   of this preference (if it is an enum type). The language code&lt;br /&gt;
	 *   should be a MediaWiki language code, e.g. &amp;quot;en&amp;quot; for English.&lt;br /&gt;
	 */&lt;br /&gt;
&lt;br /&gt;
	var wiktGadgetPrefs__registeredPrefs = {};&lt;br /&gt;
&lt;br /&gt;
	var wiktGadgetPrefs__error = (Error ?&lt;br /&gt;
		function (message) {&lt;br /&gt;
			return new Error(message);&lt;br /&gt;
		} :&lt;br /&gt;
		function (message) {&lt;br /&gt;
			return message;&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	var wiktGadgetPrefs__asciify = function (text) {&lt;br /&gt;
		return text.replace(/[^A-Za-z0-9-]/g, function (match) {&lt;br /&gt;
			if (match == &amp;quot;_&amp;quot;) {&lt;br /&gt;
				return &amp;quot;__&amp;quot;;&lt;br /&gt;
			} else {&lt;br /&gt;
				return &amp;quot;_&amp;quot; + match.charCodeAt(0).toString(16) + &amp;quot;_&amp;quot;;&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	var wiktGadgetPrefs__namespace_to_key = function (namespace) {&lt;br /&gt;
		return &amp;quot;wiktgadgetprefs-&amp;quot; + wiktGadgetPrefs__asciify(namespace);&lt;br /&gt;
	};&lt;br /&gt;
  &lt;br /&gt;
	var wiktGadgetPrefs__is_integer = function (num) {&lt;br /&gt;
		return num == (num | 0);&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	var wiktGadgetPrefs__parse_one = function (value, preference, key) {&lt;br /&gt;
		var defaultValue = preference[&amp;quot;default&amp;quot;];&lt;br /&gt;
		switch (preference.type) {&lt;br /&gt;
			case &amp;quot;boolean&amp;quot;:&lt;br /&gt;
				// data type&lt;br /&gt;
				if (typeof value != &amp;quot;boolean&amp;quot;) return defaultValue;&lt;br /&gt;
				return value;&lt;br /&gt;
			case &amp;quot;integer&amp;quot;:&lt;br /&gt;
				// data type&lt;br /&gt;
				if (typeof value != &amp;quot;number&amp;quot;) return defaultValue;&lt;br /&gt;
				// integer check&lt;br /&gt;
				if (!wiktGadgetPrefs__is_integer(value)) return defaultValue;&lt;br /&gt;
				// constraints&lt;br /&gt;
				if ((preference.minimum != null &amp;amp;&amp;amp; value &amp;lt; preference.minimum) ||&lt;br /&gt;
					(preference.maximum != null &amp;amp;&amp;amp; value &amp;gt; preference.maximum))&lt;br /&gt;
					return defaultValue;&lt;br /&gt;
				return value;&lt;br /&gt;
			case &amp;quot;string&amp;quot;:&lt;br /&gt;
				// data type&lt;br /&gt;
				if (typeof value != &amp;quot;string&amp;quot;) return defaultValue;&lt;br /&gt;
				// constraints&lt;br /&gt;
				if (preference.maximumLength != null &amp;amp;&amp;amp; value.length &amp;gt; preference.maximumLength)&lt;br /&gt;
					return defaultValue;&lt;br /&gt;
				return value;&lt;br /&gt;
			case &amp;quot;strenum&amp;quot;:&lt;br /&gt;
				// data type&lt;br /&gt;
				if (typeof value != &amp;quot;string&amp;quot;) return defaultValue;&lt;br /&gt;
				// constraints&lt;br /&gt;
				if (preference.choices.indexOf(value) &amp;lt; 0)&lt;br /&gt;
					return defaultValue;&lt;br /&gt;
				return value;&lt;br /&gt;
			case &amp;quot;object&amp;quot;:&lt;br /&gt;
				if (typeof value == &amp;quot;undefined&amp;quot;) return defaultValue;&lt;br /&gt;
				return value;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		throw wiktGadgetPrefs__error(&amp;quot;Invalid preference specification &amp;#039;&amp;quot; + key + &amp;quot;&amp;#039;&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	var wiktGadgetPrefs__parse_all = function (values, preferences) {&lt;br /&gt;
		var parsed = {};&lt;br /&gt;
		if (!values) values = {};&lt;br /&gt;
&lt;br /&gt;
		for (var key in preferences) {&lt;br /&gt;
			if (preferences.hasOwnProperty(key)) {&lt;br /&gt;
				parsed[key] = wiktGadgetPrefs__parse_one(values[key], preferences[key], key);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		return parsed;&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	var wiktGadgetPrefs__resolve = function (namespaceKey, preferences) {&lt;br /&gt;
		var resolved;&lt;br /&gt;
		var mwOptions;&lt;br /&gt;
		try {&lt;br /&gt;
			mwOptions = mw.user.options;&lt;br /&gt;
		} catch (e) {&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (!resolved &amp;amp;&amp;amp; window.localStorage &amp;amp;&amp;amp; window.localStorage.getItem(&amp;quot;anon&amp;quot; + namespaceKey) != null) {&lt;br /&gt;
			try {&lt;br /&gt;
				resolved = JSON.parse(window.localStorage.getItem(&amp;quot;anon&amp;quot; + namespaceKey));&lt;br /&gt;
			} catch (e) { }&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (!resolved &amp;amp;&amp;amp; mwOptions &amp;amp;&amp;amp; mwOptions.exists(&amp;quot;userjs-&amp;quot; + namespaceKey)) {&lt;br /&gt;
			try {&lt;br /&gt;
				resolved = JSON.parse(mwOptions.get(&amp;quot;userjs-&amp;quot; + namespaceKey));&lt;br /&gt;
			} catch (e) { }&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return wiktGadgetPrefs__parse_all(resolved || {}, preferences);&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Resolve preferences.&lt;br /&gt;
	 *&lt;br /&gt;
	 * Note that there is a maximum length imposed by MediaWiki&lt;br /&gt;
	 * on the total size of the preferences for each namespace.&lt;br /&gt;
	 *&lt;br /&gt;
	 * @param {string} namespace&lt;br /&gt;
	 * - An arbitrary string. This should be unique to each gadget.&lt;br /&gt;
	 * @param {WiktGadgetOptions} options&lt;br /&gt;
	 * - Options.&lt;br /&gt;
	 * @param {{[key: string]: WiktGadgetPreference}} preferences&lt;br /&gt;
	 * - Requested preferences, indexed by name.&lt;br /&gt;
	 * @returns {{[key: string]: any}}&lt;br /&gt;
	 */&lt;br /&gt;
	var wiktGadgetPrefs_get = function (namespace, options, preferences) {&lt;br /&gt;
		if (wiktGadgetPrefs__registeredPrefs[namespace]) {&lt;br /&gt;
			throw wiktGadgetPrefs__error(&amp;quot;wiktGadgetPrefs_get has already been called with the namespace &amp;#039;&amp;quot; + namespace + &amp;quot;&amp;#039;.&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		wiktGadgetPrefs__registeredPrefs[namespace] = {&lt;br /&gt;
			options: options,&lt;br /&gt;
			preferences: preferences&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		var namespaceKey = wiktGadgetPrefs__namespace_to_key(namespace);&lt;br /&gt;
		if (namespaceKey.length &amp;gt;= 240) {&lt;br /&gt;
			throw wiktGadgetPrefs__error(&amp;quot;Namespace key &amp;#039;&amp;quot; + namespace + &amp;quot;&amp;#039; is too long. &amp;quot; +&lt;br /&gt;
					&amp;quot;Please prefer ASCII characters A-Z, a-z, 0-9 and the hyphen, &amp;quot; +&lt;br /&gt;
					&amp;quot;as other characters need to be converted, which increases their size.&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return wiktGadgetPrefs__resolve(namespaceKey, preferences);&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	mw.wiktGadgetPrefs = {};&lt;br /&gt;
	mw.wiktGadgetPrefs.get = wiktGadgetPrefs_get;&lt;br /&gt;
&lt;br /&gt;
	// Only to be used by the preferences page.&lt;br /&gt;
	mw.wiktGadgetPrefs._namespaceToKey = wiktGadgetPrefs__namespace_to_key;&lt;br /&gt;
	mw.wiktGadgetPrefs._resolve = wiktGadgetPrefs__resolve;&lt;br /&gt;
	mw.wiktGadgetPrefs._registeredPrefs = wiktGadgetPrefs__registeredPrefs;&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
// &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>wikt&gt;Ioaxxere</name></author>
	</entry>
</feed>