మీడియావికీ:Gadget-Numeral converter.js

గమనిక: భద్రపరచిన తరువాత, మార్పులను చూడాలంటేమీ బ్రౌజరు కాషె ను తప్పించవలసి రావచ్చు. మొజిల్లా/ ఫైర్‌ఫాక్స్‌/ సఫారి: shift కీని నొక్కి పెట్టి Reload నొక్కండి, లేదా Ctrl-shift-R నొక్కండి (యాపుల్‌ మాక్‌ లో Cmd-shift-R); IE: Ctrl నొక్కి పెట్టి, Refresh నొక్కండి, లేదా Ctrl-F5 నొక్కండి; కాంకరర్‌:: Reload మీట నొక్కండి, లేదా F5 నొక్కండి; ఒపేరా ను వాడే వారు Tools→Preferences కు వెళ్ళి కాషె ను పూర్తిగా తీసివేయ వలసి ఉంటుంది.

/**
 * Convert Arabic numerals to Telugu and vice-versa.
 *
 * @revision 2.1-2012-12-19
 * @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-Numerakri.js
 * @author Daniel Friesen, 2012
 * @author Timo Tijhof, 2012
 * @author Siddhartha Ghai, 2012
 * @license CC-BY-SA 3.0
 * @license MIT
 */
/*jshint browser:true, boss:true, white:true */
/*globals jQuery */
(function (mw, $) {
	"use strict";
	// Private cache & utilities
	var el, w, num,
		/**
		 * @var {RegExp} Matcher for characters that need to be mapped.
		 */
		matchers = {
			telugu: /[0-9]/g,
			arabic: /(౧|౨|౩|౪|౫|౬|౭|౮|౯|౦)/g
		},
		msgs = {
			'option-default': {
				en: 'Default',
				te: 'అప్రమేయం'
			},
			'option-arabic': {
				en: '123'
			},
			'option-telugu': {
				en: 'Telugu',
				te: '౧౨౩'
			},
			'label-url': {
				en: '//www.mediawiki.org/wiki/MediaWiki_talk:Gadget-Numerakri.js',
				hi: '//te.wikipedia.org/wiki/వికీపీడియా:అంకెల పరివర్తనం'
			},
			'label-text': {
				en: 'Convert numerals',
				te: 'అంకెలు తెలుగులోకి మార్పు'
			},
			'label-tooltip': {
				en: 'Convert between Arabic and Telugu numerals',
				hi: 'తెలుగు అంకెలు, అరబ్బీ అంకెల మధ్య మారండి'
			}
		},
		maps = {
			telugu: {
				'0': '౧',
				'1': '౧',
				'2': '౨',
				'3': '౩',
				'4': '౪',
				'5': '౫',
				'6': '౬',
				'7': '౭',
				'8': '౮',
				'9': '౯'
			},
			arabic: {
				'౦': '0',
				'౧': '1',
				'౨': '2',
				'౩': '3',
				'౪': '4',
				'౫': '5',
				'౬': '6',
				'౭': '7',
				'౮': '8',
				'౯': '9'
			}
		},
		compatCookie = {
			'-1': 'default',
			'0' : 'arabic',
			'1': 'telugu'
		},
		// For consistency recreate these objects locally in older browsers so that
		// we can use the same constants in fallback code as well.
		NodeFilter = window.NodeFilter || {
			FILTER_ACCEPT: 1,
			FILTER_REJECT: 2,
			FILTER_SKIP: 3
		},
		Node = window.Node || {
			TEXT_NODE: 3
		};

	// Fallback for document.createTreeWalker for older browsers (IE6-8)
	function walkTheDomFallback(node, filter, apply) {
		var val = filter(node);
		switch (val) {
		case NodeFilter.FILTER_ACCEPT:
			apply(node);
			node = node.firstChild;
			break;
		case NodeFilter.FILTER_REJECT:
			node = node.nextSibling;
			break;
		case NodeFilter.FILTER_SKIP:
			node = node.firstChild;
			break;
		}
		while (node) {
			walkTheDomFallback(node, apply);
			node = node.nextSibling;
		}
	}

	function walkTheDom(filter, apply) {
		if (document.createTreeWalker) {
			w = document.createTreeWalker(document.body, NodeFilter.SHOW_ALL, filter, false);
			while (el = w.nextNode()) {
				apply(el);
			}
		} else {
			walkTheDomFallback(document.body, filter, apply);
		}
	}

	function msg(key) {
		return msgs[key][mw.config.get('wgUserLanguage')] || msgs[key].en;
	}

	/**
	 * @constructor
	 */
	function Numerakri() {
		/**
		 * @property {string} One of 'default', 'arabic' or 'telugu'.
		 *  default leaves the page unchanged (default).
		 */
		this.type = 'default';
	}

	Numerakri.prototype = {
		constructor: Numerakri,

		/**
		 * Handle matches from the regexp.
		 * @method
		 */
		convertMatch: function (match) {
			return maps[this.type][match];
		},

		/**
		 * @param {HTMLElement|TextNode} el
		 */
		filterNode: function (el) {
			var n = el.nodeName && el.nodeName.toLowerCase();
			if (n === 'input' || n === 'textarea' || $(el).hasClass('mw-numerakri-skip')) {
				return NodeFilter.FILTER_REJECT;
			}
			if (el.nodeType === Node.TEXT_NODE) {
				return NodeFilter.FILTER_ACCEPT;
			}
			return NodeFilter.FILTER_SKIP;
		},

		/**
		 * @method
		 * @param {TextNode} el
		 */
		handleTextNode: function (el) {
			el.nodeValue = el.nodeValue.replace(matchers[this.type], $.proxy(this.convertMatch, this));
		},

		isValidType: function (type) {
			return type === 'default' || (matchers[type] && maps[type]);
		},

		/**
		 * @method
		 * @param {string} type One of 'arabic' or 'telugu'.
		 * @throws Error
		 */
		setType: function (type) {
			if (!this.isValidType(type)) {
				mw.log('Unknown Numerakri type: ' + type);
				return false;
			}

			this.type = type;

			// Remember for 30 days
			$.cookie('mw-numerakri-type', type, { expires: 30, path: '/' });

			this.convertPage();
		},

		/**
		 * @return {string|undefined}
		 */
		getStoredType: function () {
			// From cookie
			var stored = $.cookie('mw-numerakri-type');

			// From cookie (old version)
			if (!stored) {
				stored = compatCookie[$.cookie('numconvert')];
			}

			return stored;
		},

		/**
		 * Do the conversion.
		 * @method
		 */
		convertPage: function () {
			if (this.type === 'default') {
				// Type 'undefined' means "don't change the page".
				return;
			}

			switch (this.type) {
			case 'arabic':
				$('ol:lang(te) li, ol.references, li.references').css('list-style-type', 'decimal');
				break;
			case 'telugu':
				$('ol:lang(te) li, ol.references, li.references').css('list-style-type', 'telugu');
				break;
			}

			walkTheDom($.proxy(this.filterNode, this), $.proxy(this.handleTextNode, this));
		},

		setupInterface: function () {
			var potlet, stored, $menu, $select,
				num = this;

			switch (mw.config.get('skin')) {
			case 'vector':
			case 'chick':
			case 'myskin':
			case 'simple':
			case 'monobook':
			case 'modern':
				$('#pt-numconvert').remove(); // Just in case
				potlet = mw.util.addPortletLink(
					'p-personal',
					msg('label-url'),
					msg('label-text'),
					'pt-numconvert',
					msg('label-tooltip'),
					null,
					mw.user.isAnon() ? '#pt-createaccount' : '#pt-userpage'
				);
				break;
			default:
				// Skin unsupported
				return;
			}

			$select = $('<select>').addClass('mw-numerakri-skip').append(
				$('<option>').val('default').text(msg('option-default')),
				$('<option>').val('arabic').text(msg('option-arabic')),
				$('<option>').val('telugu').text(msg('option-telugu'))
			);

			stored = this.getStoredType();
			if (stored) {
				// Set initial value from storage
				$select.val(stored);
				this.setType(stored);
			}

			$select.change(function () {
				num.setType(this.value);
			});

			$menu = $('<div>').addClass('mw-numerakri-menu').append($select);

			$(potlet).append($menu);
		}

	};

	num = new Numerakri();

	mw.loader.using('mediawiki.user', function () {
		$(document).ready(function () {
			num.setupInterface();
		});
	});

})(mediaWiki, jQuery);