SECURITY: jquery.makeCollapsible: Escape user-generated CSS selectors
[lhc/web/wiklou.git] / resources / src / jquery / jquery.makeCollapsible.js
index b9c13f0..32a5d3d 100644 (file)
                if ( options.wasCollapsed !== undefined ) {
                        wasCollapsed = options.wasCollapsed;
                } else {
+                       // eslint-disable-next-line no-jquery/no-class-state
                        wasCollapsed = $collapsible.hasClass( 'mw-collapsed' );
                }
 
                                .toggleClass( 'mw-collapsible-toggle-expanded', wasCollapsed );
                }
 
+               // Toggle `aria-expanded` attribute, if requested (for default and premade togglers by default).
+               if ( options.toggleARIA ) {
+                       $toggle.attr( 'aria-expanded', wasCollapsed ? 'true' : 'false' );
+               }
+
                // Toggle the text ("Show"/"Hide") within elements tagged with mw-collapsible-text
                if ( options.toggleText ) {
                        collapseText = options.toggleText.collapseText;
                        actionHandler = function ( e, opts ) {
                                var defaultOpts = {
                                        toggleClasses: true,
+                                       toggleARIA: true,
                                        toggleText: { collapseText: collapseText, expandText: expandText }
                                };
                                opts = $.extend( defaultOpts, options, opts );
                        } else {
                                collapsibleId = $collapsible.attr( 'id' ) || '';
                                if ( collapsibleId.indexOf( 'mw-customcollapsible-' ) === 0 ) {
+                                       collapsibleId = $.escapeSelector( collapsibleId );
                                        $customTogglers = $( '.' + collapsibleId.replace( 'mw-customcollapsible', 'mw-customtoggle' ) )
                                                .addClass( 'mw-customtoggle' );
                                }
 
                        // Attach event handlers to togglelink
                        $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler )
+                               .attr( 'aria-expanded', 'true' )
                                .prop( 'tabIndex', 0 );
 
                        $( this ).data( 'mw-collapsible', {
                        } );
 
                        // Initial state
+                       // eslint-disable-next-line no-jquery/no-class-state
                        if ( options.collapsed || $collapsible.hasClass( 'mw-collapsed' ) ) {
                                // One toggler can hook to multiple elements, and one element can have
                                // multiple togglers. This is the sanest way to handle that.