MediaWiki:Common.js

/* Any JavaScript here will be loaded for all users on every page load. */ /* ==Visibility toggling== */ var VisibilityToggles = window.VisibilityToggles = { // toggles[category] = [[show, hide],...]; statuses[category] = [true, false,...]; buttons = 	toggles: {},	statuses: {},	buttons: null,	// Add a new toggle, adds a Show/Hide category button in the toolbar,	// and will call show_function and hide_function once on register, and every alternate click.	register: function (category, show_function, hide_function) {		var id = 0;		if (!this.toggles[category]) {			this.toggles[category] = [];			this.statuses[category] = [];		} else {			id = this.toggles[category].length;		}		this.toggles[category].push([show_function, hide_function]);		this.statuses[category].push(this.currentStatus(category));		this.addGlobalToggle(category);		(this.statuses[category][id] ? show_function : hide_function);		return function {			var statuses = VisibilityToggles.statuses[category];			statuses[id] = !statuses[id];			VisibilityToggles.checkGlobalToggle(category);			return (statuses[id] ? show_function : hide_function);		};	},	// Add a new global toggle to the side bar	addGlobalToggle: function (category) {		if (document.getElementById('p-visibility-' + category))			return;		if (this.buttons === null) {			this.buttons = $('');			var collapsed = mw.cookie.get("vector-nav-p-visibility") === "false",				toolbox = $(' ', {						'class': "portal portlet " + (collapsed ? "collapsed" : "expanded"),						'id': 'p-visibility'					})					.append($(' Visibility '))					.append($(' ').addClass("pBody body").css("display", "block")							.append(this.buttons));			var sidebar = document.getElementById('mw-panel') || document.getElementById('column-one');			var insert = document.getElementById('p-lang') || document.getElementById('p-feedback');			if (insert)				$(insert).before(toolbox);			else				sidebar.appendChild(toolbox[0]);		}		var status = this.currentStatus(category);		var newToggle = $('').append($('', {				id: 'p-visibility-' + category,				style: 'cursor: pointer',		href: '#visibility-' + category}).on("click", function (e) {					VisibilityToggles.toggleGlobal(category);					if (e && e.preventDefault)						e.preventDefault;					else						window.event.returnValue = false;					return false;				}).text((status ? 'Hide ' : 'Show ') + category));		this.buttons.children.filter(function(i, elem) {			return elem.id < newToggle.id;		}).first.before(newToggle);

this.buttons.append(newToggle); },	// Update the toggle-all buttons when all things are toggled one way checkGlobalToggle: function (category) { var statuses = this.statuses[category]; var status = statuses[0]; for (var i = 1; i < statuses.length; i++) { if (status != statuses[i]) return; }		document.getElementById('p-visibility-' + category).innerHTML = (status ? 'Hide ' : 'Show ') + category; },	// Toggle all un-toggled elements when the global button is clicked toggleGlobal: function (category) { var status = document.getElementById('p-visibility-' + category).innerHTML.indexOf('Show ') === 0; for (var i = 0; i < this.toggles[category].length; i++) { if (this.statuses[category][i] != status) { this.toggles[category][i][status ? 0 : 1];				this.statuses[category][i] = status; }		}		document.getElementById('p-visibility-' + category).innerHTML = (status ? 'Hide ' : 'Show ') + category; var current = mw.cookie.get('Visibility'); if (!current) current = ";"; current = current.replace(';' + category + ';', ';'); if (status) current = current + category + ";"; mw.cookie.set('Visibility', current); },	currentStatus: function (category) { if (location.hash.toLowerCase.split('_')[0] == '#' + category.toLowerCase) return true; if (location.href.search(/[?](.*&)?hidecats=/) > 0) { var hidecats = location.href; hidecats = hidecats.replace(/^[^?]+[?]((?!hidecats=)[^&]*&)*hidecats=/, ''); hidecats = hidecats.replace(/&.*/, ''); hidecats = hidecats.split(','); for (var i = 0; i < hidecats.length; ++i) if (hidecats[i] == category || hidecats[i] == 'all') return false; else if (hidecats[i] == '!' + category || hidecats[i] == 'none') return true; }		if (mw.cookie.get('WiktionaryPreferencesShowNav') == 'true') return true; if ((mw.cookie.get('Visibility') || "").indexOf(';' + category + ';') >= 0) return true; // TODO check category-specific cookies return false; } };

/* == NavBars == */ var NavigationBarHide = 'Hide'; var NavigationBarShow = 'Show';

function NavToggleCategory(navFrame) { if ($(navFrame).find('table').first.is(".translations")) return "translations"; var heading = navFrame.previousSibling; while (heading) { if (/[hH][4-6]/.test(heading.nodeName)) { if (heading.getElementsByTagName('span')[1]) heading = heading.getElementsByTagName('span')[0]; return jQuery(heading).text.toLowerCase // jQuery's .text is inconsistent about whitespace: .replace(/^\s+|\s+$/g, '').replace(/\s+/g, ' ') // remove numbers added by the "Auto-number headings" pref: .replace(/^[1-9][0-9.]+ ?/, ''); } else if (/[hH][1-3]/.test(heading.nodeName)) break; heading = heading.previousSibling; }	return "other boxes"; }

function createNavToggle(navFrame) { var navHead, navContent; for (var j = 0; j < navFrame.childNodes.length; j++) { var div = navFrame.childNodes[j]; if (/(^|[^a-zA-Z0-9_\-])NavHead(?![a-zA-Z0-9_\-])/.test(div.className)) navHead = div; if (/(^|[^a-zA-Z0-9_\-])NavContent(?![a-zA-Z0-9_\-])/.test(div.className)) navContent = div; }	if (!navHead || !navContent) return; // Step 1, don't react when a subitem is clicked. $(navHead).find("a").on("click", function (e) {		if (e && e.stopPropagation)			e.stopPropagation;		else			window.event.cancelBubble = true;	}); // Step 2, toggle visibility when bar is clicked. // NOTE This function was chosen due to some funny behaviour in Safari. var $navToggle = $(''); $(' ').addClass('NavToggle') .append($navToggle) .prependTo(navHead); navHead.style.cursor = "pointer"; navHead.onclick = VisibilityToggles.register(NavToggleCategory(navFrame),		function show {			$navToggle.html(NavigationBarHide);			if (navContent)				navContent.style.display = "block";		},		function hide {			$navToggle.html(NavigationBarShow);			if (navContent)				navContent.style.display = "none";		}); }

/* ==Hidden Quotes== */ function setupHiddenQuotes(li) { var HQToggle, liComp, dl; var HQShow = 'quotations ▼'; var HQHide = 'quotations ▲'; function show { HQToggle.html(HQHide); $(li).children("ul").show; }	function hide { HQToggle.html(HQShow); $(li).children("ul").hide; }	for (var k = 0; k < li.childNodes.length; k++) { // Look at each component of the definition. liComp = li.childNodes[k]; if (liComp.nodeName.toLowerCase === "dl" && !dl) { dl = liComp; }		// If we find a ul or dl, we have quotes or example sentences, and thus need a button. if (/^(ul|UL)$/.test(liComp.nodeName)) { HQToggle = $(''); $(dl || liComp).before($(' ').addClass('HQToggle').append(HQToggle)); HQToggle.on("click", VisibilityToggles.register('quotations', show, hide)); break; }	} }

/* == View Switching == */ function showAll(elems) { for (var i = 0, length = elems.length; i < length; ++i) { var elem = elems[i]; var nodeName = elem.nodeName; elem.style.display = nodeName == 'TABLE'					? 'table' : nodeName == 'TR'						? 'table-row' : nodeName == 'TD' || nodeName == 'TH'	? 'table-cell' : nodeName == 'LI'						? 'list-item' : 'block'; } }

function viewSwitching($rootElement) { var showButtonText = $rootElement.data("vs-showtext") || 'More'; var hideButtonText = $rootElement.data("vs-hidetext") || 'Less'; var toSkip = $rootElement.find(".vsSwitcher").find("*"); var elemsToHide = $rootElement.find(".vsHide").not(toSkip); var elemsToShow = $rootElement.find(".vsShow").not(toSkip); // Find the element to place the toggle button in. var toggleElement = $rootElement.find(".vsToggleElement").not(toSkip).first; // The toggleElement becomes clickable in its entirety, but // we need to prevent this if a contained link is clicked instead. toggleElement.children("a").on("click", function (e) {		if (e && e.stopPropagation)			e.stopPropagation;		else			window.event.cancelBubble = true;	}); // Add the toggle button. var toggleButton = $(''); $(' ').addClass('NavToggle').append(toggleButton).appendTo(toggleElement); // Determine the visibility toggle category (for the links in the bar on the left). var toggleCategory = "others"; var classNames = $rootElement.attr("class").split(/\s+/); for (var i = 0; i < classNames.length; ++i) { var className = classNames[i].split('-'); if (className[0] == 'vsToggleCategory') { toggleCategory = className[1]; }	}	// Register the visibility toggle. toggleElement.css("cursor", "pointer"); toggleElement.on("click", VisibilityToggles.register(toggleCategory, function show { toggleButton.html(hideButtonText); elemsToShow.hide; showAll(elemsToHide); },		function hide { toggleButton.html(showButtonText); showAll(elemsToShow); elemsToHide.hide; })); }

/* == Apply three functions defined above == */ $.when($.ready, mw.loader.using('mediawiki.cookie')).done(function{	//NavToggles	var divs = jQuery(".NavFrame");	for (var i = 0; i < divs.length; i++) {		// XXX: some templates use a class of NavFrame for the style, but for legacy reasons, are not NavFrames		// if (divs[i].className == "NavFrame") {		createNavToggle(divs[i]);		// }	}	//quotes	if (mw.config.get('wgNamespaceNumber') === 0) {		// First, find all the ordered lists, i.e. all the series of definitions.		$('ol > li').each(function{ setupHiddenQuotes(this); });	}	//view switching	$('.vsSwitcher').each(function{ viewSwitching($(this)); }); });

jQuery(mw).on('LivePreviewDone', function (ev, sels) {	var ols = jQuery(sels.join(',')).find('ol');	for (var i = 0; i < ols.length; i++) {		for (var j = 0; j < ols[i].childNodes.length; j++) {			var li = ols[i].childNodes[j];			if (li.nodeName.toUpperCase == 'LI') {				setupHiddenQuotes(li);			}		}	} });