MediaWiki:Gadget-NavFrame.js

Z Wikipedii, wolnej encyklopedii

Uwaga: aby zobaczyć zmiany po opublikowaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.

  • Firefox / Safari: Przytrzymaj Shift podczas klikania Odśwież bieżącą stronę, lub naciśnij klawisze Ctrl+F5, lub Ctrl+R (⌘-R na komputerze Mac)
  • Google Chrome: Naciśnij Ctrl-Shift-R (⌘-Shift-R na komputerze Mac)
  • Internet Explorer / Edge: Przytrzymaj Ctrl, jednocześnie klikając Odśwież, lub naciśnij klawisze Ctrl+F5
  • Opera: Naciśnij klawisze Ctrl+F5.
/* eslint-disable no-redeclare */
/* global mw */

// i18n
var collapseCaption = "ukryj";
var expandCaption = "pokaż";

/**
 * Make sure this will work.
 */
function isBrowserCompat() {
	var supportScope = CSS && CSS.supports && CSS.supports('selector(:scope)');
	return supportScope && (typeof document.body.classList === 'object');
}

/**
 * Run when new content was added (also on doc.ready).
 * 
 * @param {Function} callback 
 */
function onNewContent(callback) {
	mw.hook( 'wikipage.content' ).add( function ( $content ) {
		if ($content && $content.length) {
			callback($content[0]);
			// seems like it should not happen, but...
			if ($content.length > 1) {
				console.warn('[collapse tables]', 'Too many contents... Only using first of '+$content.length+'.'
					+ '\nIf you see this report to [[User:Nux]] or [[WP:BAR:TE]].'
				);
			}
		}
	});
}


// TODO?: rewrite to details? https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details#browser_compatibility

/** Collapsible tables *********************************************************
 *
 *  Description: Allows tables to be collapsed, showing only the header.
 *  Legacy script, see: [[Wikipedia:NavFrame]].
 *  Creator: [[User:R. Koot]]
 *  Changes on plwiki: [[User:Holek]] et al (vide: [[MediaWiki:Common.js]])
 */

var autoCollapse = 2;
// var collapseCaption = "ukryj";
// var expandCaption = "pokaż";

function collapseTable(tableIndex) {
	var Button = document.getElementById("collapseButton" + tableIndex);
	var Table = document.getElementById("collapsibleTable" + tableIndex);

	if (!Table || !Button) {
		return false;
	}

	var Rows = Table.rows;

	if (Button.firstChild.data == collapseCaption) {
		for (var i = 1; i < Rows.length; i++) {
			Rows[i].style.display = "none";
		}
		Button.firstChild.data = expandCaption;
	} else {
		for (var i = 1; i < Rows.length; i++) {
			Rows[i].style.display = Rows[0].style.display;
		}
		Button.firstChild.data = collapseCaption;
	}
}

var CollapsibleTables_index = 0;

/** Init: Collapsible tables. */
function createCollapseButtons(baseElement) {
	var tables = baseElement.querySelectorAll("table.collapsible");
	// quick death
	if (!tables.length) {
		return;
	}

	var NavigationBoxes = [];
	for (var i = 0; i < tables.length; i++) {
		/* only add button and increment count if there is a header row to work with */
		var HeaderRow = tables[i].getElementsByTagName("tr")[0];
		if (!HeaderRow) continue;
		var Header = HeaderRow.getElementsByTagName("th")[0];
		if (!Header) continue;

		NavigationBoxes.push(tables[i]);
		tables[i].setAttribute("id", "collapsibleTable" + CollapsibleTables_index);

		var Button = document.createElement("span");
		var ButtonLink = document.createElement("a");
		var ButtonText = document.createTextNode(collapseCaption);

		Button.style.styleFloat = "right";
		Button.style.cssFloat = "right";
		Button.style.fontWeight = "normal";
		Button.style.textAlign = "right";
		Button.style.width = "6em";

		ButtonLink.style.color = Header.style.color;
		ButtonLink.setAttribute("id", "collapseButton" + CollapsibleTables_index);
		ButtonLink.setAttribute("href", "#collapseButton" + CollapsibleTables_index);
		ButtonLink.setAttribute("data-nav-tab", CollapsibleTables_index);
		ButtonLink.addEventListener('click', function (e) {
			e.preventDefault();
			var tableIndex = this.getAttribute("data-nav-tab");
			collapseTable(tableIndex);
		});
		ButtonLink.appendChild(ButtonText);

		Button.appendChild(document.createTextNode("["));
		Button.appendChild(ButtonLink);
		Button.appendChild(document.createTextNode("]"));

		Header.insertBefore(Button, Header.childNodes[0]);
		CollapsibleTables_index++;
	}

	for (var i = 0; i < NavigationBoxes.length; i++) {
		if (NavigationBoxes[i].classList.contains("collapsed") || (CollapsibleTables_index >= autoCollapse && NavigationBoxes[i].classList.contains("autocollapse"))) {
			collapseTable(i);
		} else if (NavigationBoxes[i].classList.contains("innercollapse")) {
			var element = NavigationBoxes[i];
			// eslint-disable-next-line no-cond-assign
			while (element = element.parentNode) {
				if (element.classList.contains("outercollapse")) {
					collapseTable(i);
					break;
				}
			}
		}
	}
}

if (isBrowserCompat()) {
	onNewContent(createCollapseButtons);
}


/** Dynamic Navigation Bars (experimental) *************************************
 *
 *  Description: See [[Wikipedia:NavFrame]].
 */

// set up the words in your language
var NavigationBarHide = collapseCaption;
var NavigationBarShow = expandCaption;

// shows and hides content and picture (if available) of navigation bars
// Parameters:
//     indexNavigationBar: the index of navigation bar to be toggled
// eslint-disable-next-line no-unused-vars
function toggleNavigationBar(indexNavigationBar) {
	var NavToggle = document.getElementById("NavToggle" + indexNavigationBar);
	var NavFrame = document.getElementById("NavFrame" + indexNavigationBar);

	if (!NavFrame || !NavToggle) {
		return false;
	}

	// if was shown (hiding)
	if (NavToggle.firstChild.data == NavigationBarHide) {
		NavFrame.querySelectorAll(':scope > .NavPic').forEach(function(NavChild) {
			NavChild.style.display = 'none';
		});
		NavFrame.querySelectorAll(':scope > .NavContent').forEach(function(NavChild) {
			NavChild.style.display = 'none';
		});
		NavToggle.firstChild.data = NavigationBarShow;
		NavToggle.setAttribute('aria-expanded', 'false');
	// if was hidden (show)
	} else if (NavToggle.firstChild.data == NavigationBarShow) {
		NavFrame.querySelectorAll(':scope > .NavPic').forEach(function(NavChild) {
			NavChild.style.display = 'block';
		});
		NavFrame.querySelectorAll(':scope > .NavContent').forEach(function(NavChild) {
			NavChild.style.display = 'block';
		});
		NavToggle.firstChild.data = NavigationBarHide;
		NavToggle.setAttribute('aria-expanded', 'true');
	}
}

// for global id
var NavFrame_index = 0;

/**
 * Init: NavFrame elements.
 * 
 * Adds show/hide-button to navigation bars.
 */
function createNavigationBarToggleButton(baseElement) {
	var divs = baseElement.querySelectorAll("div.NavFrame");
	// quick death
	if (!divs.length) {
		return;
	}

	// iterate over all < div >-elements
	for (var i = 0; i < divs.length; i++) {
		var NavFrame = divs[i];
		// skip invalid (don't have required classes)
		if (!NavFrame.querySelector(':scope > .NavPic, :scope > .NavContent')) {
			continue;
		}
		NavFrame_index++;
		var NavToggle = document.createElement("button");
		NavToggle.className = 'NavToggle';
		NavToggle.setAttribute('id', 'NavToggle' + NavFrame_index);
		NavToggle.setAttribute("data-nav-bar", NavFrame_index);
		NavToggle.addEventListener('click', function (e) {
			e.preventDefault();
			var indexNavigationBar = this.getAttribute("data-nav-bar");
			toggleNavigationBar(indexNavigationBar);
		});

		var isCollapsed = NavFrame.classList.contains("collapsed");
		/*
			* Check if any children are already hidden.  This loop is here for backwards compatibility:
			* the old way of making NavFrames start out collapsed was to manually add style="display:none"
			* to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make
			* the content visible without JavaScript support), the new recommended way is to add the class
			* "collapsed" to the NavFrame itself, just like with collapsible tables.
			*/
		NavFrame.querySelectorAll(':scope > .NavPic, :scope > .NavContent').forEach(function(NavChild) {
			if (NavChild.style.display == 'none') {
				isCollapsed = true;
			}
		});
		if (isCollapsed) {
			NavFrame.querySelectorAll(':scope > .NavPic, :scope > .NavContent').forEach(function(NavChild) {
				NavChild.style.display = 'none';
			});
		}
		var NavToggleText = document.createTextNode(isCollapsed ? NavigationBarShow : NavigationBarHide);
		NavToggle.appendChild(NavToggleText);
		NavToggle.setAttribute('aria-expanded', isCollapsed ? 'false' : 'true');

		// Find the NavHead and attach the toggle link
		NavFrame.querySelectorAll(':scope > .NavHead').forEach(function(NavChild) {
			NavChild.appendChild(NavToggle);
		});
		NavFrame.setAttribute('id', 'NavFrame' + NavFrame_index);
	}
}

if (isBrowserCompat()) {
	onNewContent(createNavigationBarToggleButton);
}