MediaWiki:Common.js
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.
/** * Collapsible Sidebar (Debug Build) for MW 1.44 (Vector + Vector 2022) * - Writes verbose logs to the console * - Inserts a real <span> arrow (▶), so you see it even if :before fails * - No jquery.cookie, no extra modules * * Toggle logging at runtime with: window.MWSidebarDebug = true/false */ (function () { // Turn on debug by default; you can turn off in the console if too chatty. window.MWSidebarDebug = true; function log() { if (window.MWSidebarDebug && typeof console !== 'undefined') { console.log.apply(console, ['[SidebarCollapsible]'].concat([].slice.call(arguments))); } } function warn() { if (typeof console !== 'undefined') { console.warn.apply(console, ['[SidebarCollapsible]'].concat([].slice.call(arguments))); } } var skin = mw.config.get('skin'); log('Init start. Detected skin =', skin); function findTopList($panel) { // Works for Vector/Vector-2022 portlets and (fallback) legacy .portal markup return $panel.find('> .vector-menu-content > .vector-menu-content-list, > .body > ul').first(); } function initOnce($root) { // Find all sidebar portlets that look like menus var $panels = $('#mw-panel .vector-menu-portal, .vector-menu-portal', $root); if (!$panels.length) { warn('No .vector-menu-portal found. Are you using Vector/Vector-2022?'); } else { log('Found', $panels.length, 'portal(s).'); } $panels.each(function (idx, el) { var $panel = $(el); var id = $panel.attr('id') || ('panel#' + idx); var $list = findTopList($panel); if (!$list.length) { warn('Panel has no UL list:', id, $panel.get(0)); return; } var $items = $list.children('li'); log('Panel', id, ':', $items.length, 'top-level <li> item(s).'); $items.each(function (i, li) { var $li = $(li); var $sub = $li.children('ul'); if (!$sub.length) { // Not a collapsible candidate return; } // Mark as collapsible and hide sub-list (if not already) $li.addClass('collapsible-header'); if (!$li.children('.mw-collapsible-arrow').length) { // Insert a real arrow character so it’s guaranteed visible $li.prepend($('<span class="mw-collapsible-arrow" aria-hidden="true">▶</span>')); } $sub.hide(); // Log header text for reference var headerText = ($li.find('> a').first().text() || $li.clone().children().remove().end().text() || '') .trim() .replace(/\s+/g, ' '); log('Registered collapsible item', i, 'in', id, 'header=', headerText); // Click to toggle (but let actual links work) $li.off('.mwCollapsibleSidebar') // avoid duplicate binding .on('click.mwCollapsibleSidebar', function (e) { if ($(e.target).closest('a').length) { // Click on a link inside; do not toggle log('Link click passthrough for header:', headerText); return; } e.preventDefault(); var willOpen = !$li.hasClass('open'); $li.toggleClass('open'); $sub.stop(true, true).slideToggle(200); log('Toggled', (willOpen ? 'open' : 'closed') + ':', headerText); }); }); }); } // Run on DOM ready and on content re-renders mw.loader.using('mediawiki.util').then(function () { $(function () { console.group && console.group('[SidebarCollapsible] bootstrap'); initOnce($(document)); console.groupEnd && console.groupEnd(); }); mw.hook('wikipage.content').add(function ($c) { log('wikipage.content hook fired (re-init on dynamic content).'); initOnce($c); }); }); })();