Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
       🚧 True to our name, we’re still a work in progress. 🚧
   
       You’re welcome to explore, but account registration is currently invite-only as we finalize the setup. 
       Join our forum or follow Mastodon for updates. 
       Full Wiki launch coming soon!
   

MediaWiki:Gadget-subpagenav.js

MediaWiki interface page
Revision as of 12:31, 22 March 2026 by Anthony (talk | contribs) (Edit to allow template to work without metadata, and a simple "{{SubpageNav}}")

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.
/* =============================================================================
   Gadget-subpagenav.js
   Handles touch dropdowns and auto-builds nested menus from Special:PrefixIndex
   ============================================================================= */
( function () {
    $( function () {
        var $navLinks = $( '.subpage-nav-links' );
        if ( !$navLinks.length ) return;

        // --- PART 1: Auto-Builder for Special:PrefixIndex ---
        $navLinks.find( '.subpage-auto-list' ).each( function () {
            var $autoContainer = $( this );
            var $newRootUl = $( '<ul></ul>' );
            
            // Loop through every link generated by PrefixIndex
            $autoContainer.find( 'a' ).each( function () {
                var $a = $( this ).clone();
                var fullPath = $a.text(); // e.g., "Guides/Basic Setup"
                var parts = fullPath.split( '/' );
                
                var $currentLevel = $newRootUl;
                
                // Build the folder structure
                for ( var i = 0; i < parts.length; i++ ) {
                    var part = parts[i];
                    var isLast = ( i === parts.length - 1 );
                    
                    // Look for existing folder/dropdown at this level
                    var $existingLi = $currentLevel.children( 'li[data-nav-part="' + part + '"]' );
                    
                    if ( !$existingLi.length ) {
                        $existingLi = $( '<li></li>' ).attr( 'data-nav-part', part );
                        
                        if ( isLast ) {
                            // It's the final link item
                            $a.text( part ); // Rename link to just the final part
                            $existingLi.append( $a );
                        } else {
                            // It's a folder (dropdown trigger)
                            $existingLi.append( $( '<span></span>' ).text( part ) );
                            $existingLi.append( '<ul></ul>' );
                        }
                        $currentLevel.append( $existingLi );
                    }
                    
                    // Move deeper into the tree
                    $currentLevel = $existingLi.children( 'ul' );
                }
            } );
            
            // Replace the messy PrefixIndex HTML with our clean nested list
            $autoContainer.replaceWith( $newRootUl );
        } );

        // --- PART 2: Dropdown Toggles (Carets & Mobile) ---
        var $dropdowns = $navLinks.find( 'li' ).has( 'ul' );
        $dropdowns.addClass( 'has-dropdown' );
        $dropdowns.children( 'a, span' ).append( '<span class="subpage-nav-caret">▼</span>' );

        $navLinks.on( 'click', '.has-dropdown > a, .has-dropdown > span', function ( e ) {
            var $parentLi = $( this ).parent();
            
            // Close siblings
            $parentLi.siblings( '.has-dropdown' ).removeClass( 'is-open' );
            
            // Toggle current
            $parentLi.toggleClass( 'is-open' );

            if ( $( this ).is( 'span' ) ) {
                e.preventDefault();
            }
        } );

        $( document ).on( 'click', function ( e ) {
            if ( !$( e.target ).closest( '.subpage-nav-links' ).length ) {
                $( '.subpage-nav-links .has-dropdown' ).removeClass( 'is-open' );
            }
        } );
    } );
}() );