Fix TOC display for printing
[mediawiki.git] / skins / vector / collapsibleNav.js
blob45258e50ade2174a49a1d879763f39ddf6365d4c
1 /**
2  * Collapsible navigation for Vector
3  */
4 ( function ( mw, $ ) {
5         'use strict';
6         var map;
8         // Use the same function for all navigation headings - don't repeat
9         function toggle( $element ) {
10                 var isCollapsed = $element.parent().is( '.collapsed' );
12                 $.cookie(
13                         'vector-nav-' + $element.parent().attr( 'id' ),
14                         isCollapsed,
15                         { 'expires': 30, 'path': '/' }
16                 );
18                 $element
19                         .parent()
20                         .toggleClass( 'expanded' )
21                         .toggleClass( 'collapsed' )
22                         .find( '.body' )
23                         .slideToggle( 'fast' );
24                 isCollapsed = !isCollapsed;
26                 $element
27                         .find( '> a' )
28                         .attr( {
29                                 'aria-pressed': isCollapsed ? 'false' : 'true',
30                                 'aria-expanded': isCollapsed ? 'false' : 'true'
31                         } );
32         }
34         /* Browser Support */
36         map = {
37                 // Left-to-right languages
38                 ltr: {
39                         // Collapsible Nav is broken in Opera < 9.6 and Konqueror < 4
40                         opera: [['>=', 9.6]],
41                         konqueror: [['>=', 4.0]],
42                         blackberry: false,
43                         ipod: false,
44                         iphone: false,
45                         ps3: false
46                 },
47                 // Right-to-left languages
48                 rtl: {
49                         opera: [['>=', 9.6]],
50                         konqueror: [['>=', 4.0]],
51                         blackberry: false,
52                         ipod: false,
53                         iphone: false,
54                         ps3: false
55                 }
56         };
57         if ( !$.client.test( map ) ) {
58                 return true;
59         }
61         $( function ( $ ) {
62                 var $headings, tabIndex;
64                 /* General Portal Modification */
66                 // Always show the first portal
67                 $( '#mw-panel > .portal:first' ).addClass( 'first persistent' );
68                 // Apply a class to the entire panel to activate styles
69                 $( '#mw-panel' ).addClass( 'collapsible-nav' );
70                 // Use cookie data to restore preferences of what to show and hide
71                 $( '#mw-panel > .portal:not(.persistent)' )
72                         .each( function ( i ) {
73                                 var id = $(this).attr( 'id' ),
74                                         state = $.cookie( 'vector-nav-' + id );
75                                 $(this).find( 'ul:first' ).attr( 'id', id + '-list' );
76                                 // Add anchor tag to heading for better accessibility
77                                 $( this ).find( 'h3' ).wrapInner(
78                                         $( '<a>' )
79                                                 .attr( {
80                                                         href: '#',
81                                                         'aria-haspopup': 'true',
82                                                         'aria-controls': id + '-list',
83                                                         role: 'button'
84                                                 } )
85                                                 .click( false )
86                                 );
87                                 // In the case that we are not showing the new version, let's show the languages by default
88                                 if (
89                                         state === 'true' ||
90                                         ( state === null && i < 1 ) ||
91                                         ( state === null && id === 'p-lang' )
92                                 ) {
93                                         $(this)
94                                                 .addClass( 'expanded' )
95                                                 .removeClass( 'collapsed' )
96                                                 .find( '.body' )
97                                                 .hide() // bug 34450
98                                                 .show();
99                                         $(this).find( 'h3 > a' )
100                                                 .attr( {
101                                                         'aria-pressed': 'true',
102                                                         'aria-expanded': 'true'
103                                                 } );
104                                 } else {
105                                         $(this)
106                                                 .addClass( 'collapsed' )
107                                                 .removeClass( 'expanded' );
108                                         $(this).find( 'h3 > a' )
109                                                 .attr( {
110                                                         'aria-pressed': 'false',
111                                                         'aria-expanded': 'false'
112                                                 } );
113                                 }
114                                 // Re-save cookie
115                                 if ( state !== null ) {
116                                         $.cookie( 'vector-nav-' + $(this).attr( 'id' ), state, { 'expires': 30, 'path': '/' } );
117                                 }
118                         } );
120                 /* Tab Indexing */
122                 $headings = $( '#mw-panel > .portal:not(.persistent) > h3' );
124                 // Get the highest tab index
125                 tabIndex = $( document ).lastTabIndex() + 1;
127                 // Fix the search not having a tabindex
128                 $( '#searchInput' ).attr( 'tabindex', tabIndex++ );
130                 // Make it keyboard accessible
131                 $headings.attr( 'tabindex', function () {
132                         return tabIndex++;
133                 });
135                 // Toggle the selected menu's class and expand or collapse the menu
136                 $( '#mw-panel' )
137                         .delegate( '.portal:not(.persistent) > h3', 'keydown', function ( e ) {
138                                 // Make the space and enter keys act as a click
139                                 if ( e.which === 13 /* Enter */ || e.which === 32 /* Space */ ) {
140                                         toggle( $(this) );
141                                 }
142                         } )
143                         .delegate( '.portal:not(.persistent) > h3', 'mousedown', function ( e ) {
144                                 if ( e.which !== 3 ) { // Right mouse click
145                                         toggle( $(this) );
146                                         $(this).blur();
147                                 }
148                                 return false;
149                         } );
150         });
152 }( mediaWiki, jQuery ) );