MediaWiki:Common.js

From EQOA Sandstorm Wiki
Revision as of 20:11, 16 May 2026 by RenodorDev (talk | contribs)
Jump to navigationJump to search

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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/* Any JavaScript here will be loaded for all users on every page load. */

(function () {
    function rawPage(title) {
        return mw.config.get('wgScript') +
            '?title=' + encodeURIComponent(title) +
            '&action=raw&ctype=text/javascript';
    }

    function loadScriptUrl(url) {
        return $.getScript(url);
    }

    function loadWikiScript(title) {
        return loadScriptUrl(rawPage(title));
    }

    function applyWikiTheme(theme) {
        var isLight = theme === 'light';
        var button = document.getElementById('eqoa-theme-toggle');

        document.documentElement.classList.toggle('eqoa-theme-light', isLight);
        document.documentElement.classList.toggle('eqoa-theme-dark', !isLight);

        if (document.body) {
            document.body.classList.toggle('eqoa-theme-light', isLight);
            document.body.classList.toggle('eqoa-theme-dark', !isLight);
        }

        try {
            localStorage.setItem('eqoa-wiki-theme', isLight ? 'light' : 'dark');
            localStorage.setItem('eqoa-builder-theme', isLight ? 'light' : 'dark');
            localStorage.setItem('eqoa-cm-theme', isLight ? 'light' : 'dark');
        } catch (e) {}

        if (button) {
            button.innerHTML = isLight ? '☾' : '☼';
            button.title = isLight ? 'Switch to Dark Theme' : 'Switch to White Theme';
            button.setAttribute(
                'aria-label',
                isLight ? 'Switch to Dark Theme' : 'Switch to White Theme'
            );
        }

        if (window.dispatchEvent) {
            window.dispatchEvent(new CustomEvent('eqoa-wiki-theme-change', {
                detail: {
                    theme: isLight ? 'light' : 'dark'
                }
            }));
        }
    }

    function getSavedWikiTheme() {
        try {
            return localStorage.getItem('eqoa-wiki-theme') === 'light'
                ? 'light'
                : 'dark';
        } catch (e) {
            return 'dark';
        }
    }

    function ensureThemeButton() {
        var button = document.getElementById('eqoa-theme-toggle');

        if (!button) {
            button = document.createElement('button');
            button.id = 'eqoa-theme-toggle';
            button.type = 'button';
            button.className = 'eqoa-theme-toggle';

            button.addEventListener('click', function () {
                var isLight = document.body.classList.contains('eqoa-theme-light');
                applyWikiTheme(isLight ? 'dark' : 'light');
            });

            document.body.appendChild(button);
        }

        applyWikiTheme(getSavedWikiTheme());
    }

    function initRaidChecks() {
        var containers = document.querySelectorAll('.raid-checkboxify');

        Array.prototype.forEach.call(containers, function (container) {
            var links = container.querySelectorAll('a');

            Array.prototype.forEach.call(links, function (a) {
                var cb;
                var label;
                var key;
                var stored;

                if (a.classList.contains('raid-processed')) return;

                cb = document.createElement('input');
                cb.type = 'checkbox';
                cb.className = 'raid-checkbox-input';
                cb.style.marginRight = '8px';
                cb.style.verticalAlign = 'middle';

                label = document.createElement('label');
                label.style.display = 'block';
                label.style.cursor = 'pointer';

                a.parentNode.insertBefore(label, a);
                label.appendChild(cb);
                label.appendChild(a);

                a.classList.add('raid-processed');

                key = 'raidcheck:' +
                    (document.title || location.pathname) +
                    ':' +
                    a.getAttribute('href');

                try {
                    stored = localStorage.getItem(key);
                    if (stored === '1') cb.checked = true;
                } catch (e) {}

                cb.addEventListener('change', function () {
                    try {
                        if (cb.checked) {
                            localStorage.setItem(key, '1');
                        } else {
                            localStorage.removeItem(key);
                        }
                    } catch (e) {}
                });
            });
        });
    }

    function initItemFilters() {
        var table = document.getElementById('items-found-here-table');
        var box;
        var filters;
        var clearButton;

        if (!table) return;
        if (document.getElementById('items-filter-box')) return;

        box = document.createElement('div');
        box.id = 'items-filter-box';
        box.className = 'items-filter-box';

        box.innerHTML =
            '<b>Item Filters</b><br>' +
            'Item: <input type="text" id="filter-item"> ' +
            'Dropped By: <input type="text" id="filter-mob"> ' +
            'Class: <input type="text" id="filter-class"> ' +
            'Lvl >= <input type="number" id="filter-lvl-min"> ' +
            'DMG >= <input type="number" id="filter-dmg-min"> ' +
            'AC >= <input type="number" id="filter-ac-min"> ' +
            'HP >= <input type="number" id="filter-hp-min"> ' +
            'POW >= <input type="number" id="filter-pow-min"> ' +
            '<button id="clear-item-filters" type="button">Clear</button>';

        table.parentNode.insertBefore(box, table);

        filters = {
            item: document.getElementById('filter-item'),
            mob: document.getElementById('filter-mob'),
            className: document.getElementById('filter-class'),
            lvlMin: document.getElementById('filter-lvl-min'),
            dmgMin: document.getElementById('filter-dmg-min'),
            acMin: document.getElementById('filter-ac-min'),
            hpMin: document.getElementById('filter-hp-min'),
            powMin: document.getElementById('filter-pow-min')
        };

        clearButton = document.getElementById('clear-item-filters');

        function getCellText(row, index) {
            return (row.cells[index] ? row.cells[index].textContent : '').toLowerCase();
        }

        function getCellNumber(row, index) {
            var text = row.cells[index] ? row.cells[index].textContent.trim() : '';
            var num = parseFloat(text.replace(/[^\d.-]/g, ''));
            return isNaN(num) ? 0 : num;
        }

        function getInputNumber(input) {
            var num;

            if (!input || input.value === '') return null;

            num = parseFloat(input.value);
            return isNaN(num) ? null : num;
        }

        function filterTable() {
            var itemText = filters.item.value.toLowerCase();
            var mobText = filters.mob.value.toLowerCase();
            var classText = filters.className.value.toLowerCase();

            var lvlMin = getInputNumber(filters.lvlMin);
            var dmgMin = getInputNumber(filters.dmgMin);
            var acMin = getInputNumber(filters.acMin);
            var hpMin = getInputNumber(filters.hpMin);
            var powMin = getInputNumber(filters.powMin);

            var i;
            var row;
            var show;

            for (i = 1; i < table.rows.length; i++) {
                row = table.rows[i];
                show = true;

                if (itemText && getCellText(row, 0).indexOf(itemText) === -1) show = false;
                if (mobText && getCellText(row, 1).indexOf(mobText) === -1) show = false;
                if (classText && getCellText(row, 2).indexOf(classText) === -1) show = false;

                if (lvlMin !== null && getCellNumber(row, 3) < lvlMin) show = false;
                if (dmgMin !== null && getCellNumber(row, 4) < dmgMin) show = false;
                if (acMin !== null && getCellNumber(row, 5) < acMin) show = false;
                if (hpMin !== null && getCellNumber(row, 13) < hpMin) show = false;
                if (powMin !== null && getCellNumber(row, 15) < powMin) show = false;

                row.style.display = show ? '' : 'none';
            }
        }

        Object.keys(filters).forEach(function (key) {
            filters[key].addEventListener('input', filterTable);
        });

        clearButton.addEventListener('click', function () {
            Object.keys(filters).forEach(function (key) {
                filters[key].value = '';
            });

            filterTable();
        });
    }

    function loadBuilderScripts() {
        loadWikiScript('MediaWiki:CharacterBuilderData.js')
            .done(function () {
                $.when(
                    loadScriptUrl('https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js'),
                    loadScriptUrl('https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.5.0/lz-string.min.js'),
                    loadScriptUrl('https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js')
                ).always(function () {
                    loadWikiScript('MediaWiki:CharacterBuilder.js')
                        .fail(function (error) {
                            console.error('Character Builder failed to load:', error);
                        });
                });
            })
            .fail(function (error) {
                console.error('Character Builder data failed to load:', error);
            });
    }

    function loadClassMasteryScripts() {
        loadWikiScript('MediaWiki:ClassMasteryData.js')
            .done(function () {
                loadWikiScript('MediaWiki:ClassMasteryRawData.js')
                    .always(function () {
                        loadWikiScript('MediaWiki:ClassMasteryCalculator.js')
                            .fail(function (error) {
                                console.error('Class Mastery calculator failed to load:', error);
                            });
                    });
            })
            .fail(function (error) {
                console.error('Class Mastery data failed to load:', error);
            });
    }

    window.EQOA_APPLY_WIKI_THEME = applyWikiTheme;
    window.EQOA_GET_WIKI_THEME = getSavedWikiTheme;

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

    mw.hook('wikipage.content').add(function () {
        ensureThemeButton();
        initRaidChecks();
        initItemFilters();
    });

    mw.loader.using('mediawiki.util').then(function () {
        loadBuilderScripts();
        loadClassMasteryScripts();
    });
})();