MediaWiki:Common.js: Difference between revisions

From GladiusRO Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
/*
/*
  * ==========================================================
  * ==========================================================
  * GladiusRO Wiki - Permanent Sidebar Configuration
  * GladiusRO Wiki - Complete Interface Configuration
  *
  *
* Functions:
  * 1. Keep Contents permanently in the left sidebar.
  * 1. Keep Contents permanently in the left sidebar.
  * 2. Hide technical links from logged-out players.
  * 2. Place Contents below Tools.
  * 3. Show technical links to logged-in administrators/editors.
* 3. Hide technical navigation from normal players.
* 4. Hide View source and View history from normal players.
  * 5. Show administrative controls to administrators.
  * ==========================================================
  * ==========================================================
  */
  */


(function (mw) {
(function (mw, $) {
     'use strict';
     'use strict';


    var observerRunning = false;
     var refreshTimer = null;
     var refreshTimer = null;
    var observerStarted = false;


     /*
     /*
     * Find the left sidebar used by the current wiki skin.
     * Check whether the current account is an administrator.
    * MediaWiki administrators belong to the sysop group.
     */
     */
     function getGladiusSidebar() {
     function isAdministrator() {
        var userGroups = mw.config.get('wgUserGroups') || [];
 
        return userGroups.indexOf('sysop') !== -1;
    }
 
    /*
    * Find the existing left sidebar.
    */
    function getSidebar() {
         return document.getElementById('mw-panel') ||
         return document.getElementById('mw-panel') ||
             document.getElementById('mw-navigation') ||
             document.getElementById('mw-navigation') ||
Line 26: Line 37:


     /*
     /*
     * Check whether the current visitor is logged in.
     * Move Contents permanently into the left sidebar.
    *
    * Logged-out player:
    * wgUserName is null.
    *
    * Logged-in administrator/editor:
    * wgUserName contains the account name.
     */
     */
     function isLoggedIn() {
     function moveContentsToSidebar() {
         return mw.config.get('wgUserName') !== null;
         var sidebar = getSidebar();
    }
        var tools = document.getElementById('p-tb');
        var toc = document.getElementById('toc');
        var container =
            document.getElementById('gladius-sidebar-toc');
 
        if (!sidebar) {
            return;
        }


    /*
        /*
    * Create or retrieve the permanent TOC container.
        * Do not create an empty container on pages
    */
        * that do not have a Table of Contents.
    function getTOCContainer() {*        var container =
        */
          * document.getElementById('gladius-sidebar-toc');
        if (!toc && !container) {
            return;
        }


        /*
        * Create the sidebar container when required.
        */
         if (!container) {
         if (!container) {
             container = document.createElement('div');
             container = document.createElement('div');
Line 49: Line 66:
             container.id = 'gladius-sidebar-toc';
             container.id = 'gladius-sidebar-toc';
             container.className = 'portal mw-portlet';
             container.className = 'portal mw-portlet';
             container.setAttribute(
             container.setAttribute(
                 'role',
                 'role',
                 'navigation'
                 'navigation'
             );
             );
             container.setAttribute(
             container.setAttribute(
                 'aria-label',
                 'aria-label',
                 'Page contents'
                 'Page contents'
             );
             );
        }
        return container;
    }
    /*
    * Keep Contents permanently in the left sidebar.
    */
    function keepContentsInSidebar() {
        var sidebar = getGladiusSidebar();
        var toc = document.getElementById('toc');
        if (!sidebar) {
            return false;
         }
         }


         /*
         /*
         * Do not create an empty Contents panel on pages
         * Move the original article Contents into
         * without a TOC.
         * the permanent sidebar container.
         */
         */
        var existingContainer =
         if (toc && toc.parentNode !== container) {
            document.getElementById('gladius-sidebar-toc');
             container.appendChild(toc);
 
         if (!toc && !existingContainer) {
             return false;
         }
         }
        var container =
            existingContainer || getTOCContainer();


         /*
         /*
         * Attach the Contents container directly to
         * Place Contents immediately below Tools.
        * the left sidebar.
         *
         *
         * This makes placement independent of whether
         * When Tools is hidden from normal players,
         * Tools is visible or hidden.
         * Contents will appear below Main page.
         */
         */
         if (container.parentNode !== sidebar) {
         if (tools && tools.parentNode) {
            if (
                container.parentNode !== tools.parentNode ||
                container.previousElementSibling !== tools
            ) {
                tools.parentNode.insertBefore(
                    container,
                    tools.nextSibling
                );
            }
        } else if (container.parentNode !== sidebar) {
             sidebar.appendChild(container);
             sidebar.appendChild(container);
         }
         }


         /*
         /*
         * Move the original article TOC into the
         * Hide the container on pages without Contents.
        * permanent sidebar container.
        */
        if (toc && toc.parentNode !== container) {
            container.appendChild(toc);
        }
 
        /*
        * Show the container when it contains a TOC.
        * Hide it on pages without a TOC.
         */
         */
         if (container.querySelector('#toc')) {
         if (container.querySelector('#toc')) {
Line 119: Line 118:
             );
             );
         }
         }
        return true;
     }
     }


     /*
     /*
     * Hide one element completely.
     * Hide an interface element.
     */
     */
     function hideElement(element) {
     function hideElement(element) {
         if (!element) {
         if (element) {
             return;
             element.style.setProperty(
                'display',
                'none',
                'important'
            );
         }
         }
        element.style.setProperty(
            'display',
            'none',
            'important'
        );
     }
     }


     /*
     /*
     * Restore an element when an administrator/editor
     * Restore an interface element.
    * is logged in.
     */
     */
     function restoreElement(element) {
     function showElement(element) {
         if (!element) {
         if (element) {
             return;
             element.style.removeProperty('display');
         }
         }
        element.style.removeProperty('display');
     }
     }


     /*
     /*
     * Hide or show technical navigation links.
     * Hide or show technical navigation.
     */
     */
     function updatePlayerNavigation() {
     function updateTechnicalNavigation() {
         var loggedIn = isLoggedIn();
         var administrator = isAdministrator();


        /*
         var restrictedElements = [
        * IDs commonly used by MediaWiki sidebar items.
        */
         var technicalElementIds * [
             'n-recentchanges',
             'n-recentchanges',
             'n-randompage',
             'n-randompage',
Line 168: Line 157:
         ];
         ];


         technicalElementIds.forEach(function (id) {
         restrictedElements.forEach(function (elementId) {
             var element = document.getElementById(id);
             var element =
                document.getElementById(elementId);


             if (loggedIn) {
             if (administrator) {
                 restoreElement(element);
                 showElement(element);
             } else {
             } else {
                 hideElement(element);
                 hideElement(element);
Line 178: Line 168:
         });
         });


         var sidebar = getGladiusSidebar();
        /*
        * Fallback for older or custom skins using
        * different navigation element IDs.
        */
         var sidebar = getSidebar();


         if (!sidebar) {
         if (!sidebar) {
Line 184: Line 178:
         }
         }


        /*
         var restrictedLinkNames = [
        * Fallback for older/custom skins where the
        * navigation items use different IDs.
        */
         var hiddenTexts = [
             'recent changes',
             'recent changes',
             'random page',
             'random page',
Line 194: Line 184:
             'what links here',
             'what links here',
             'related changes',
             'related changes',
            'upload file',
             'special pages',
             'special pages',
             'printable version',
             'printable version',
Line 200: Line 191:
         ];
         ];


         var links = sidebar.q*erySelectorAll('a');
         var links = sidebar.querySelectorAll('a');


         Arra*.prototype.forEach.call(
         Array.prototype.forEach.call(
        *  links,
            links,
             function (lin*) {
             function (link) {
                 var text = (li*k.textContent || '')
                 var linkText = (link.textContent || '')
                     .replace(/\s+/g, ' ')
                     .replace(/\s+/g, ' ')
                     .trim()
                     .trim()
                     .toLowerCase();
                     .toLowerCase();


                 var href =
                 if (
                    link.getAttribute('href') || '';
                     restrictedLinkNames.indexOf(
 
                         linkText
                var hideThisLink =
                     ) === -1
                     hiddenTexts.indexOf(text) !== -1 ||
                 ) {
                    href.indexOf(
                         'mediawiki.org/wiki/Help'
                     ) !== -1;
 
                 if (!hideThisLink) {
                     return;
                     return;
                 }
                 }


                /*
                * Hide or restore the complete list row,
                * avoiding empty spaces in the sidebar.
                */
                 var row =
                 var row =
                     link.closest('li') ||
                     link.closest('li') ||
                     link.parentElement;
                     link.parentElement;


                 if (loggedIn) {
                 if (administrator) {
                     restoreElement(row);
                     showElement(row);
                     restoreElement(link);
                     showElement(link);
                 } else {
                 } else {
                     hideElement(row || link);
                     hideElement(row || link);
Line 239: Line 221:
             }
             }
         );
         );
    }


        /*
    /*
        * Fallback: find a section with the visible
    * Hide View source and View history from
        * heading "Tools" if #p-tb is unavailable.
    * everyone except administrators.
        */
    */
         var sidebarElements =
    function updatePageTabs() {
            sidebar.querySelectorAll('div, h3, h4');
         var administrator = isAdministrator();


         Array.prototype.forEach.call(
         var restrictedTabs = [
            sidebarElements,
            'ca-viewsource',
            function (element) {
            'ca-history'
                var headingText =
        ];
                    (element.textContent || '')
                        .replace(/\s+/g, ' ')
                        .trim()
                        .toLowerCase();


                /*
        restrictedTabs.forEach(function (tabId) {
                * Avoid matching the whole sidebar, whose
            var tab = document.getElementById(tabId);
                * text may include the word "Tools".
                */
                if (
                    headingText === 'tools' &&
                    !loggedIn
                ) {
                    var toolsSection =
                        element.closest(
                            '.portal, .mw-portlet'
                        );


                    if (toolsSection) {
            if (administrator) {
                        hideElement(toolsSection);
                showElement(tab);
                    }
            } else {
                 }
                 hideElement(tab);
             }
             }
         );
         });
     }
     }


     /*
     /*
     * Apply all sidebar corrections.
     * Apply all GladiusRO interface settings.
     *
     *
     * Contents is moved first. Technical links are hidden
     * Contents must be moved before Tools is hidden.
    * afterward, ensuring that hiding Tools does not prevent
    * the TOC from being moved.
     */
     */
     function applyGladiusSidebar() {
     function applyGladiusInterface() {
         keepContentsInSidebar();
         moveContentsToSidebar();
         updatePlayerNavigation();
         updateTechnicalNavigation();
        updatePageTabs();
     }
     }


     /*
     /*
     * Watch for MediaWiki or skin changes.
     * Automatically correct Contents if MediaWiki
    *
     * recreates it inside the article.
     * If MediaWiki places Contents inside the article again,
    * the observer moves Contents back to the sidebar.
     */
     */
     function startGladiusObserve*() {
     function startInterfaceObserver() {
         if (
         if (
             obse*verRunning ||
             observerStarted ||
             !document.body ||
             !document.body ||
             typeof MutationObserver === 'undefined'
             typeof MutationObserver === 'undefined'
Line 304: Line 270:
         }
         }


         observerRunning = true;
         observerStarted = true;


         var observer = new MutationObserver(function () {
         var observer = new MutationObserver(function () {
Line 310: Line 276:


             refreshTimer = window.setTimeout(
             refreshTimer = window.setTimeout(
                 applyGladiusSidebar,
                 applyGladiusInterface,
                 100
                 100
             );
             );
Line 322: Line 288:


     /*
     /*
     * Initial setup.
     * Initial startup.
     */
     */
     function initialiseGladiusSidebar() {
     function initialiseGladiusInterface() {
         applyGladiusSidebar();
         applyGladiusInterface();
         startGladiusObserver();
         startInterfaceObserver();


         /*
         /*
         * Additional checks for older skins and
         * Additional checks for delayed skin components.
        * delayed ResourceLoader components.
         */
         */
         window.setTimeout(
         window.setTimeout(
             applyGladiusSidebar,
             applyGladiusInterface,
             250
             250
         );
         );


         window.setTimeout(
         window.setTimeout(
             applyGladiusSidebar,
             applyGladiusInterface,
             800
             800
         );
         );


         window.setTimeout(
         window.setTimeout(
             applyGladiusSidebar,
             applyGladiusInterface,
             1600
             1600
         );
         );
     }
     }


    /*
    * Start when the document is ready.
    */
     if (document.readyState === 'loading') {
     if (document.readyState === 'loading') {
         document.addEventListener(
         document.addEventListener(
             'DOMContentLoaded',
             'DOMContentLoaded',
             initialiseGladiusSidebar
             initialiseGladiusInterface
         );
         );
     } else {
     } else {
         initialiseGladiusSidebar();
         initialiseGladiusInterface();
     }
     }


    /*
    * Run again after images and skin assets finish loading.
    */
     window.addEventListener(
     window.addEventListener(
         'load',
         'load',
         applyGladiusSidebar
         applyGladiusInterface
     );
     );


     /*
     /*
     * Run after MediaWiki dynamically updates article content.
     * Reapply after MediaWiki updates article content.
     */
     */
     if (mw.hook) {
     if (mw.hook) {
         mw.ho*k('wikipage.content').add(function*() {
         mw.hook('wikipage.content').add(function () {
             window.setTimeout*
             window.setTimeout(
                 applyGladiusSideb*r,
                 applyGladiusInterface,
                 100
                 100
          *);
            );
         });
         });
     }
     }


}(mediaWiki)*;
}(mediaWiki, jQuery));

Latest revision as of 06:42, 2 August 2026

/*
 * ==========================================================
 * GladiusRO Wiki - Complete Interface Configuration
 *
 * 1. Keep Contents permanently in the left sidebar.
 * 2. Place Contents below Tools.
 * 3. Hide technical navigation from normal players.
 * 4. Hide View source and View history from normal players.
 * 5. Show administrative controls to administrators.
 * ==========================================================
 */

(function (mw, $) {
    'use strict';

    var refreshTimer = null;
    var observerStarted = false;

    /*
     * Check whether the current account is an administrator.
     * MediaWiki administrators belong to the sysop group.
     */
    function isAdministrator() {
        var userGroups = mw.config.get('wgUserGroups') || [];

        return userGroups.indexOf('sysop') !== -1;
    }

    /*
     * Find the existing left sidebar.
     */
    function getSidebar() {
        return document.getElementById('mw-panel') ||
            document.getElementById('mw-navigation') ||
            document.querySelector('.sidebar');
    }

    /*
     * Move Contents permanently into the left sidebar.
     */
    function moveContentsToSidebar() {
        var sidebar = getSidebar();
        var tools = document.getElementById('p-tb');
        var toc = document.getElementById('toc');
        var container =
            document.getElementById('gladius-sidebar-toc');

        if (!sidebar) {
            return;
        }

        /*
         * Do not create an empty container on pages
         * that do not have a Table of Contents.
         */
        if (!toc && !container) {
            return;
        }

        /*
         * Create the sidebar container when required.
         */
        if (!container) {
            container = document.createElement('div');

            container.id = 'gladius-sidebar-toc';
            container.className = 'portal mw-portlet';

            container.setAttribute(
                'role',
                'navigation'
            );

            container.setAttribute(
                'aria-label',
                'Page contents'
            );
        }

        /*
         * Move the original article Contents into
         * the permanent sidebar container.
         */
        if (toc && toc.parentNode !== container) {
            container.appendChild(toc);
        }

        /*
         * Place Contents immediately below Tools.
         *
         * When Tools is hidden from normal players,
         * Contents will appear below Main page.
         */
        if (tools && tools.parentNode) {
            if (
                container.parentNode !== tools.parentNode ||
                container.previousElementSibling !== tools
            ) {
                tools.parentNode.insertBefore(
                    container,
                    tools.nextSibling
                );
            }
        } else if (container.parentNode !== sidebar) {
            sidebar.appendChild(container);
        }

        /*
         * Hide the container on pages without Contents.
         */
        if (container.querySelector('#toc')) {
            container.style.removeProperty('display');
        } else {
            container.style.setProperty(
                'display',
                'none',
                'important'
            );
        }
    }

    /*
     * Hide an interface element.
     */
    function hideElement(element) {
        if (element) {
            element.style.setProperty(
                'display',
                'none',
                'important'
            );
        }
    }

    /*
     * Restore an interface element.
     */
    function showElement(element) {
        if (element) {
            element.style.removeProperty('display');
        }
    }

    /*
     * Hide or show technical navigation.
     */
    function updateTechnicalNavigation() {
        var administrator = isAdministrator();

        var restrictedElements = [
            'n-recentchanges',
            'n-randompage',
            'n-help',
            'n-help-mediawiki',
            'n-helppage',
            'p-tb'
        ];

        restrictedElements.forEach(function (elementId) {
            var element =
                document.getElementById(elementId);

            if (administrator) {
                showElement(element);
            } else {
                hideElement(element);
            }
        });

        /*
         * Fallback for older or custom skins using
         * different navigation element IDs.
         */
        var sidebar = getSidebar();

        if (!sidebar) {
            return;
        }

        var restrictedLinkNames = [
            'recent changes',
            'random page',
            'help about mediawiki',
            'what links here',
            'related changes',
            'upload file',
            'special pages',
            'printable version',
            'permanent link',
            'page information'
        ];

        var links = sidebar.querySelectorAll('a');

        Array.prototype.forEach.call(
            links,
            function (link) {
                var linkText = (link.textContent || '')
                    .replace(/\s+/g, ' ')
                    .trim()
                    .toLowerCase();

                if (
                    restrictedLinkNames.indexOf(
                        linkText
                    ) === -1
                ) {
                    return;
                }

                var row =
                    link.closest('li') ||
                    link.parentElement;

                if (administrator) {
                    showElement(row);
                    showElement(link);
                } else {
                    hideElement(row || link);
                }
            }
        );
    }

    /*
     * Hide View source and View history from
     * everyone except administrators.
     */
    function updatePageTabs() {
        var administrator = isAdministrator();

        var restrictedTabs = [
            'ca-viewsource',
            'ca-history'
        ];

        restrictedTabs.forEach(function (tabId) {
            var tab = document.getElementById(tabId);

            if (administrator) {
                showElement(tab);
            } else {
                hideElement(tab);
            }
        });
    }

    /*
     * Apply all GladiusRO interface settings.
     *
     * Contents must be moved before Tools is hidden.
     */
    function applyGladiusInterface() {
        moveContentsToSidebar();
        updateTechnicalNavigation();
        updatePageTabs();
    }

    /*
     * Automatically correct Contents if MediaWiki
     * recreates it inside the article.
     */
    function startInterfaceObserver() {
        if (
            observerStarted ||
            !document.body ||
            typeof MutationObserver === 'undefined'
        ) {
            return;
        }

        observerStarted = true;

        var observer = new MutationObserver(function () {
            window.clearTimeout(refreshTimer);

            refreshTimer = window.setTimeout(
                applyGladiusInterface,
                100
            );
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    /*
     * Initial startup.
     */
    function initialiseGladiusInterface() {
        applyGladiusInterface();
        startInterfaceObserver();

        /*
         * Additional checks for delayed skin components.
         */
        window.setTimeout(
            applyGladiusInterface,
            250
        );

        window.setTimeout(
            applyGladiusInterface,
            800
        );

        window.setTimeout(
            applyGladiusInterface,
            1600
        );
    }

    if (document.readyState === 'loading') {
        document.addEventListener(
            'DOMContentLoaded',
            initialiseGladiusInterface
        );
    } else {
        initialiseGladiusInterface();
    }

    window.addEventListener(
        'load',
        applyGladiusInterface
    );

    /*
     * Reapply after MediaWiki updates article content.
     */
    if (mw.hook) {
        mw.hook('wikipage.content').add(function () {
            window.setTimeout(
                applyGladiusInterface,
                100
            );
        });
    }

}(mediaWiki, jQuery));