MediaWiki:Gadget-CollapsibleNav.js

From NBITTRPG Wiki

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/**
 * Collapsible navigation for Timeless, based on the Collapsible Navigation from Vector.
 * Derived from Dragalia Lost Wiki by Elaeagnifolia (https://dragalialost.wiki/w/User:Elaeagnifolia) 
 * Licensed under CC BY-NC-SA 4.0 (https://creativecommons.org/licenses/by-nc-sa/4.0/)
 * @source https://dragalialost.wiki/w/MediaWiki:Gadget-CollapsibleNav.js
 * @source /core/skins/vector/collapsibleNav.js
 */
mw.loader.using('oojs-ui-widgets').then(function() {
	'use strict';

	var desktopSelectors = ['#site-tools', '#page-tools', '#catlinks-sidebar', '#other-languages'];
	var globalSelectors = ['#site-navigation'];

	function toggle($element, forceSetting) {
		var isCollapsed = $element.parent().is('.collapsed');

		if (forceSetting == 'expand' && !isCollapsed ||
			forceSetting == 'close' && isCollapsed) {
			return;
		}

		$.cookie(
			'timeless-nav-' + $element.parent().attr('id'),
			isCollapsed, {
				'expires': 30,
				'path': '/'
			}
		);

		$element
			.parent()
			.toggleClass('expanded')
			.toggleClass('collapsed')
			.find('.mw-portlet-body')
			.slideToggle('fast');
		isCollapsed = !isCollapsed;

		$element
			.find('> a')
			.attr({
				'aria-pressed': isCollapsed ? 'false' : 'true',
				'aria-expanded': isCollapsed ? 'false' : 'true'
			});
	}

	function run(selectors) {
		$(function($) {
			var $headings, tabIndex;

			selectors.forEach(function(selector) {
				// Apply a class to the entire panel to activate styles
				$(selector).addClass('collapsible-nav');
				$(selector + ' > .sidebar-inner > div > h3:not("#p-navigation-label")').addClass('collapsible-nav-header');

				// Use cookie data to restore preferences of what to show and hide
				$(selector + ' .mw-portlet')
					.each(function(i) {
						var id = $(this).attr('id'),
							state = $.cookie('timeless-nav-' + id);
						$(this).find('ul:first').attr('id', id + '-list');
						// Add anchor tag to heading for better accessibility
						$(this).find('h3:not("#p-navigation-label")').wrapInner(
							$('<a>')
							.attr({
								href: '#',
								'aria-haspopup': 'true',
								'aria-controls': id + '-list',
								role: 'button'
							})
							.click(false)
						);
						// In the case that we are not showing the new version, let's show the languages by default
						if (
							state === 'true' ||
							state === null
						) {
							$(this)
								.addClass('expanded')
								.removeClass('collapsed')
								.find('.mw-portlet-body')
								.hide() // bug 34450
								.show();
							$(this).find('h3:not("#p-navigation-label") > a')
								.attr({
									'aria-pressed': 'true',
									'aria-expanded': 'true'
								});
						} else {
							$(this)
								.addClass('collapsed')
								.removeClass('expanded');
							$(this).find('h3:not("#p-navigation-label") > a')
								.attr({
									'aria-pressed': 'false',
									'aria-expanded': 'false'
								});
						}
						// Re-save cookie
						if (state !== null) {
							$.cookie('timeless-nav-' + $(this).attr('id'), state, {
								'expires': 30,
								'path': '/'
							});
						}
					});

				/* Tab Indexing */
				// Make it keyboard accessible
				$headings = $(selector + ' .mw-portlet > h3:not("#p-navigation-label")');
				$headings.attr('tabindex', '0');

				// Toggle the selected menu's class and expand or collapse the menu
				$(selector)
					.on('keydown', '.mw-portlet > h3:not("#p-navigation-label")', function(e) {
						// Make the space and enter keys act as a click
						if (e.which === 13 /* Enter */ || e.which === 32 /* Space */ ) {
							toggle($(this));
						}
					})
					.on('mousedown', '.mw-portlet > h3:not("#p-navigation-label")', function(e) {
						if (e.which !== 3) { // Right mouse click
							toggle($(this));
							$(this).blur();
						}
						return false;
					});
			});
		});
	}

	var initialState = {};
	desktopSelectors.forEach(function(selector) {
		initialState[selector] = $(selector).clone(true);
	});

	var navigationPortletExpandState = $.cookie('timeless-nav-p-navigation');
	var toggleText = 'Close All';
	if (navigationPortletExpandState !== 'true' && navigationPortletExpandState !== null) {
		toggleText = 'Expand All';
	}

	if ($(window).width() > 1099) {
		run(desktopSelectors.concat(globalSelectors));
	} else {
		run(globalSelectors);
	}

	function resizeCheck() {
		if ($(window).width() > 1099) {
			if (!$(desktopSelectors[0]).hasClass('collapsible-nav')) {
				run(desktopSelectors);
			}
		} else {
			if ($(desktopSelectors[0]).hasClass('collapsible-nav')) {
				desktopSelectors.forEach(function(selector) {
					$(selector).replaceWith(initialState[selector].clone(true));
				});
			}
		}
	}

	window.onresize = resizeCheck;
});