MediaWiki:Gadget-AGprefs.js

From Wiktionary, the free dictionary
Jump to navigation Jump to search

Note – after saving, you may have to bypass your browser’s cache to see the changes.

  • Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
  • Konqueror and Chrome: click Reload or press F5;
  • Opera: clear the cache in Tools → Preferences;
  • Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.

See also: Special:Gadgets.


/** per-browser preferences page **/

/*jshint undef:true, boss:true, latedef:true, shadow:true */
/*global mw, jQuery, OO */

'use strict'; 

var gadgetList = { '': {} };
var prefs;
try {
	prefs = window.localStorage.getItem('AGprefs');
} catch (e) {
	prefs = jQuery.cookie('AGprefs');
}
prefs = prefs ? JSON.parse(prefs) : { gadgets: {}, modules: {}, sheets: {}, scripts: {} };

var uiContent = document.getElementById('mw-content-text');

var api = new mw.Api();
api.get({
	action: 'query',
	titles: 'MediaWiki:Gadgets-definition',
	prop: 'revisions',
	rvprop: 'content',
	rvlimit: 1
}).then(function (result) {
	var m, mm, wikitext;
	for (var pageid in result.query.pages) {
		wikitext = result.query.pages[pageid].revisions[0]['*'];
	}
	var lines = wikitext.split('\n'), msgQueue = {}, curGroup = '';
	for (var i = 0; i < lines.length; ++i) {
		if (m = /^==\s*(.*?)\s*==$/.exec(lines[i])) {
			msgQueue['Gadget-section-' + m[1]] = true;
			gadgetList[curGroup = m[1]] = {};
		} else if (m = /^\*\s*([A-Za-z][A-Za-z0-9_\-]*)\s*(?:\[(.*?)\])?\|(.*)\s*$/.exec(lines[i])) {
			msgQueue['Gadget-' + m[1]] = true;
			var gadget = gadgetList[curGroup][m[1]] = {
				options: {},
				css: [],
				js: []
			};

			if (m[2]) {
				var opts = m[2].split('|');
				for (var j = 0; j < opts.length; ++j) {
					if (mm = /^(.*)=(.*)$/.exec(opts[j]))
						gadget.options[mm[1]] = mm[2];
					else
						gadget.options[opts[j]] = true;
				}
			}
			
			var files = m[3].split('|');
			for (var j = 0; j < files.length; ++j) {
				if (/\.css$/.test(files[j]))
					gadget.css.push(files[j]);
				else
					gadget.js.push(files[j]);
			}
		}
	}

	var validGadgets = {}, validModules = {}, validJS = {}, validCSS = {};
	for (var group in gadgetList) {
		for (var name in gadgetList[group]) {
			var gadget = gadgetList[group][name];
			validGadgets[name] = true;
			if (gadget.options.ResourceLoader || (gadget.js.length === 0)) {
				validModules['ext.gadget.' + name] = true;
			} else {
				for (var i = 0; i < gadget.css.length; ++i)
					validJS[gadget.css[i]] = true;
				for (var i = 0; i < gadget.js.length; ++i)
					validCSS[gadget.js[i]] = true;
			}
		}
	}
	
	for (var key in prefs.gadgets)
		if (!(key in validGadgets))
			delete prefs.gadgets[key];
	for (var key in prefs.modules)
		if (!(key in validModules))
			delete prefs.modules[key];
	for (var key in prefs.sheets)
		if (!(key in validCSS))
			delete prefs.sheets[key];
	for (var key in prefs.scripts)
		if (!(key in validJS))
			delete prefs.scripts[key];

	var msgs = {};
	jQuery.Deferred(function (self) {
		/*jshint loopfunc:true */
		var promises = [], queue = Object.keys(msgQueue);
		for (var i = 0; i < queue.length; i += 50) {
			promises.push(api.get({
				action: 'query',
				meta: 'allmessages',
				amenableparser: '1',
				ammessages: queue.slice(i, i + 50).join("|")
			}).then(function (result) {
				for (var i = 0; i < result.query.allmessages.length; ++i) {
					var mesg = result.query.allmessages[i];
					if ('missing' in mesg)
						msgs[mesg.name] = '&lt;' + mesg.name + '>';
					else
						msgs[mesg.name] = mesg['*'];
				}
			}));
		}

		jQuery.when.apply(jQuery, promises).then(function () {
			self.resolveWith(msgQueue);
		}, function (data) {
			self.rejectWith(data);
		});
	}).then(function (msgQueue) {
		function makeListItem(name, gadget) {
			var button = new OO.ui.CheckboxInputWidget({
				selected: name in prefs.gadgets ? prefs.gadgets[name] : !!gadget.options['default']
			});
			button.on('change', function(e) {
				var checked = button.isSelected();
				prefs.gadgets[name] = checked;
				if (gadget.options.ResourceLoader || (gadget.js.length === 0)) {
					prefs.modules['ext.gadget.' + name] = checked;
				} else {
					for (var i = 0; i < gadget.css.length; ++i)
						prefs.sheets[gadget.css[i]] = checked;
					for (var i = 0; i < gadget.js.length; ++i)
						prefs.scripts[gadget.js[i]] = checked;
				}
			});
			
			var html = (msgs['Gadget-' + name] || ("&lt;Gadget-" + name + "&gt;")).replace(/\[\[(?:(.*?)\|)?(.*?)\]\]/g, function (whole, page, label) {
				return '<a href="' + mw.util.getUrl(page || label).replace(/[<"&>]/g, function (c) {
					return '&#' + c.charCodeAt(0) + ';';
				}) + '">' + label + '</a>';
			});
			var field = new OO.ui.FieldLayout( button, { label: jQuery('<span>' + html + '</span>'), align: 'inline' } );
			
			// styling fix
			field.$element.children().css('max-width', 'none');
			
			return field.$element[0];
		}
		
		var uiPrefs = document.createElement('div');

		for (var group in gadgetList) {
			var uiHeader = document.createElement('h2');
			var uiList = document.createElement('div');
			uiHeader.textContent = msgs['Gadget-section-' + group];
			for (var name in gadgetList[group]) {
				var gadget = gadgetList[group][name];

				if ('rights' in gadget.options || gadget.options['hidden'])
					continue; // XXX: we just assume we do not have the necessary rights (or the gadget is hidden, don't show those)

				if ('skins' in gadget.options)
					if (gadget.options.skins.split(',').indexOf(mw.config.get('skin')) === -1)
						continue;

				var uiItem = makeListItem(name, gadget);
				uiList.appendChild(uiItem);
			}
			if (uiList.hasChildNodes()) {
				if (group !== '')
					uiPrefs.appendChild(uiHeader);
				uiPrefs.appendChild(uiList);
			}
		}
		
		var uiSave = new OO.ui.ButtonWidget({
			label: 'Apply and reload',
			flags: ['primary', 'progressive']
		});
		var uiReset = new OO.ui.ButtonWidget({
			label: 'Reset to defaults',
			flags: 'destructive'
		});
		
		uiSave.on('click', function () {
			var value = JSON.stringify(prefs);
			try {
				window.localStorage.setItem('AGprefs', value);
			} catch (e) {
				jQuery.cookie('AGprefs', value, { expire: 90 });
			}
			location.reload();
		});
		
		uiReset.on('click', function () {
			try {
				window.localStorage.removeItem('AGprefs');
			} catch (e) {
				/* ignore */
			}
			jQuery.cookie('AGprefs', null);
			location.reload();
		});

		var uiButtonContainer = document.createElement('div');
		uiButtonContainer.style.marginTop = '1em';
		
		uiButtonContainer.appendChild(uiSave.$element[0]);
		uiButtonContainer.appendChild(document.createTextNode(" "));
		uiButtonContainer.appendChild(uiReset.$element[0]);

		uiPrefs.appendChild(uiButtonContainer);
		uiContent.appendChild(uiPrefs);
	}, function () {
		console.error('getting gadget names failed', arguments);
	});
}, function () {
	console.error('getting Gadgets-definition failed', arguments);
});