MediaWiki:Gadget-CollapsibleNav.js

From Wikipedia

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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
 * Collapsible navigation for Vector
 * @source  mediawiki/extensions/CollapsibleVector
 */
( function ( mw, $ ) {
	'use strict';
	var map;

	// Use the same function for all navigation headings - don't repeat
	function toggle( $element ) {
		var isCollapsed = $element.parent().is( '.collapsed' );

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

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

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

	/* Browser Support */

	map = {
		// Left-to-right languages
		ltr: {
			// Collapsible Nav is broken in Opera < 9.6 and Konqueror < 4
			opera: [ [ '>=', 9.6 ] ],
			konqueror: [ [ '>=', 4.0 ] ],
			blackberry: false,
			ipad: [ [ '>=', 6.0 ] ],
			ipod: [ [ '>=', 6.0 ] ],
			iphone: [ [ '>=', 6.0 ] ],
			ps3: false
		},
		// Right-to-left languages
		rtl: {
			opera: [ [ '>=', 9.6 ] ],
			konqueror: [ [ '>=', 4.0 ] ],
			blackberry: false,
			ipad: [ [ '>=', 6.0 ] ],
			ipod: [ [ '>=', 6.0 ] ],
			iphone: [ [ '>=', 6.0 ] ],
			ps3: false
		}
	};
	if ( !$.client.test( map ) ) {
		return true;
	}

	$( function ( $ ) {
		var $headings;

		/* General Portal Modification */

		// Always show the first portal
		$( '#mw-panel > .portal:first' ).addClass( 'first persistent' );
		// Apply a class to the entire panel to activate styles
		$( '#mw-panel' ).addClass( 'collapsible-nav' );
		// Use cookie data to restore preferences of what to show and hide
		$( '#mw-panel > .portal:not(.persistent)' ).each( function ( i ) {
			var id = $( this ).attr( 'id' ), state = $.cookie( 'vector-nav-' + id );
			$( this ).find( 'ul:first' ).attr( 'id', id + '-list' );
			// Add anchor tag to heading for better accessibility
			$( this ).find( 'h3' ).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 && i < 1 ) ||
				( state === null && id === 'p-lang' )
			) {
				$( this )
					.addClass( 'expanded' )
					.removeClass( 'collapsed' )
					.find( '.body' )
					// Phab T36450
					.hide()
					.show();
				$( this ).find( 'h3 > a' )
					.attr( {
						'aria-pressed': 'true',
						'aria-expanded': 'true'
					} );
			} else {
				$( this )
					.addClass( 'collapsed' )
					.removeClass( 'expanded' );
				$( this ).find( 'h3 > a' )
					.attr( {
						'aria-pressed': 'false',
						'aria-expanded': 'false'
					} );
			}
			// Re-save cookie
			if ( state !== null ) {
				$.cookie( 'vector-nav-' + $( this ).attr( 'id' ), state, { expires: 30, path: '/' } );
			}
		} );

		/* Tab Indexing */

		$headings = $( '#mw-panel > .portal:not(.persistent) > h3' );

		// Make it keyboard accessible
		$headings.attr( 'tabindex', '0' );

		// Toggle the selected menu's class and expand or collapse the menu
		$( '#mw-panel' )
			.on( 'keydown', '.portal:not(.persistent) > h3', 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', '.portal:not(.persistent) > h3', function ( e ) {
				// Right mouse click
				if ( e.which !== 3 ) {
					toggle( $( this ) );
					$( this ).blur();
				}
				return false;
			} );
	} );

}( mediaWiki, jQuery ) );