Snippets/Toggle between dropdown menus and tabs

From MediaWiki.org
Jump to navigation Jump to search
How to use Snippets
List of Snippets
Crystal Clear action run.png
Toggle between dropdown menus and tabs
Language(s): JavaScript , CSS
Compatible with: MediaWiki 1.24+ (Vector)

Description[edit]

Enables the user to toggle between drop-down menus and tabs in the Vector skin.

This code works best as a gadget. Load it using the following code: MenuTabsToggle[ResourceLoader|dependencies=mediawiki.cookie]|MenuTabsToggle.js|MenuTabsToggle.css

Code[edit]

MenuTabsToggle.js:

/*
 * Toggle between dropdown menus and tabs.
 *
 * @dependencies mediawiki.cookie
 * @source en.wikipedia.org/wiki/MediaWiki:Gadget-MenuTabsToggle.js
 * @source imported as of 2011-10-04 from [[User:Edokter/MenuTabsToggle.js]] / [[User:Edokter/MenuTabsToggle.css]]
 * @revision 3.4
 * @author: Edokter ([[User:Edokter]])
 */

$( document ).ready( function() {
	var portlet = [];
	var portletId = [];
	var portletToggle = [];
	var toggleDiv = '<div class="vectorToggle" id="$1"><span><a href="#"></a></span></div>';

	/* Portlets to exclude */
	var excludePortlets = [ 'p-namespaces', 'p-twinkle' ];

	/* MenuToTabs */
	function MenuToTabs( portlet, id ) {
		portlet.removeClass( 'vectorMenu' ).addClass( 'vectorTabs' ).css( 'margin-left', '-1px' )
			.find( 'div.menu > ul' ).unwrap()
			.find( 'li > a' ).wrap( '<span></span>' );
		portlet.find( 'li.icon-collapsed' ).removeClass( 'icon-collapsed' ).addClass( 'icon' );
		mw.cookie.set( id, 'tabs', { prefix: 'vector-tabs-' } );
	}

	/* TabsToMenu */
	function TabsToMenu( portlet, id ) {
		portlet.removeClass( 'vectorTabs' ).addClass( 'vectorMenu' ).css( 'margin-left', '' )
			.find( 'ul' ).wrap( '<div class="menu"></div>' )
			.find( 'span > a' ).unwrap();
		portlet.find( 'li.icon' ).removeClass( 'icon' ).addClass( 'icon-collapsed' );
		mw.cookie.set( id, 'menu', { prefix: 'vector-tabs-' } );
	}

	/* Initialize */
	if ( !mw.config.get( 'skin' ) == 'vector' ) {
		return;
	}

	// Unbind events from vector.js
	$( 'div.vectorMenu' ).find( 'h3' ).off();

	// Enumerate all portlets
	$( 'div.vectorMenu, div.vectorTabs' ).each( function(i) {
		portlet[i] = $( this );
		portletId[i] = portlet[i].attr( 'id' );

		// Skip excluded portlets
		if ( $.inArray( portletId[i], excludePortlets ) == -1 ) {

			// Disable collapsible tabs
			portlet[i].find( 'li.collapsible' ).removeClass( 'collapsible' );

			portletToggle[i] = $( toggleDiv.replace( '$1', portletId[i] + '-toggle' ) );
			// Left or right?
			if ( portlet[i].parent().attr( 'id' ) == 'left-navigation' ) {
				portletToggle[i]
					.addClass( 'toggle-left' )
					.insertBefore( portlet[i].find( 'ul' ) );
			} else {
				portletToggle[i]
					.addClass( 'toggle-right' )
					.insertAfter( portlet[i].find( 'ul' ) );
			}

			// Menu or Tabs?
			if ( portlet[i].hasClass( 'vectorMenu' ) ) {
				if ( mw.cookie.get( portletId[i], 'vector-tabs-' ) == 'tabs' ) {
					MenuToTabs( portlet[i], portletId[i] );
				}
			}
			else if ( portlet[i].hasClass( 'vectorTabs' ) ) {
				portlet[i].find( 'h3' )
					.wrapInner( '<span></span>' )
					.append( '<a href="#"></a>' );
				if ( mw.cookie.get( portletId[i], 'vector-tabs-' ) == 'menu' ) {
					TabsToMenu( portlet[i], portletId[i] );
				}
			}

			// Assign key and mouse events
			portlet[i].delegate( 'h3 a', 'click', function( event ) {
				event.preventDefault();
			} );
			portlet[i].delegate( 'h3 a', 'mousedown', function( event ) {
				if ( event.which != 3 ) {
					var ul = portlet[i].find( 'ul' );
					ul.animate( { height: 'hide' }, 125, function() {
						MenuToTabs( portlet[i], portletId[i] );
						ul.animate( { width: 'show' }, 125 );
					} );
				}
			} );

			portletToggle[i].delegate( 'a', 'click', function( event ) {
				event.preventDefault();
			} );
			portletToggle[i].delegate( 'a', 'mousedown', function( event ) {
				if ( event.which != 3 ) {
					var ul = portlet[i].find( 'ul' );
					ul.animate( { width: 'hide' }, 125, function() {
						TabsToMenu( portlet[i], portletId[i] );
						ul.animate( { height: 'show' }, 125 );
					} );
				}
			} );
		}
	} );
} );

MenuTabsToggle.css:

/* Toggle between dropdown menus and tabs.
 *
 * @dependencies jquery.cookie
 * @source en.wikipedia.org/wiki/MediaWiki:Gadget-MenuTabsToggle.css
 * @source imported as of 2011-10-04 from [[User:Edokter/MenuTabsToggle.js]] / [[User:Edokter/MenuTabsToggle.css]]
 * @revision 3.3
 * @author: Edokter ([[User:Edokter]])
 */

div#mw-head div#right-navigation div.vectorMenu > h3 {
	/* @embed */
	background-image: url(/w/skins/Vector/images/tab-break.png);
}

div.vectorMenu#p-variants #mw-vector-current-variant {
	display: inline-block;
	float: left;
	font-size: 0.8em;
	padding-left: 0.5em;
	padding-top: 1.375em;
	font-weight: normal;
	border: none;
}

div.vectorMenu {
	-webkit-transition: none;
	transition: none;
}

div.vectorMenu div.menu {
	z-index: 101;
}

div.vectorMenu div.vectorToggle {
	display: none;
}

div.vectorTabs div.vectorToggle {
	float: left;
	height: 2.5em;
}

div.vectorToggle span a {
	padding: 0;
	height: 2.5em;
	width: 23px;
}

/* @noflip */
div.vectorToggle.toggle-left {
	/* @embed */
	background: url(/w/skins/Vector/images/arrow-collapsed-ltr.png) 50% 60% no-repeat;
	background-image: -moz-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/arrow-collapsed-ltr.svg);
	background-image: -webkit-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/arrow-collapsed-ltr.svg);
	background-image: linear-gradient(transparent, transparent), url(/w/skins/Vector/images/arrow-collapsed-ltr.svg);
}

/* @noflip */
div.vectorToggle.toggle-right {
	/* @embed */
	background: url(/w/skins/Vector/images/arrow-collapsed-rtl.png) 50% 60% no-repeat;
	background-image: -moz-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/arrow-collapsed-rtl.svg);
	background-image: -webkit-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/arrow-collapsed-rtl.svg);
	background-image: linear-gradient(transparent, transparent), url(/w/skins/Vector/images/arrow-collapsed-rtl.svg);
}