MediaWiki:Common.js: відмінності між версіями

нема опису редагування
Немає опису редагування
Немає опису редагування
Рядок 2: Рядок 2:
// MediaWiki:Common.js — Mafia Closed Circle — ФІНАЛЬНА ВЕРСІЯ
// MediaWiki:Common.js — Mafia Closed Circle — ФІНАЛЬНА ВЕРСІЯ
// ============================================================
// ============================================================
// ============================================================
// FULL-WIDTH PAGE DETECTION
// ============================================================
var MCC_FULLWIDTH_PAGES = [
    'page-Ігри', 'page-Статистика', 'page-Перша_статистика',
    'page-Фіналіст', 'page-Сезони', 'page-Гравці',
    'page-Фундація', 'page-Призовий_фонд', 'page-Призові',
    'page-Титули', 'page-Період'
];
function isMccFullwidth() {
    var bodyClasses = document.body.className;
    for (var i = 0; i < MCC_FULLWIDTH_PAGES.length; i++) {
        if (bodyClasses.indexOf(MCC_FULLWIDTH_PAGES[i]) !== -1) return true;
    }
    return false;
}


// ============================================================
// ============================================================
Рядок 778: Рядок 797:
// ============================================================
// ============================================================
// FILTERS FOR SEASON "Запис ігор" WIDE TABLE
// FILTERS FOR SEASON "Запис ігор" WIDE TABLE
// Runs on page load for static wiki tables
// Only runs on season/tournament pages (not full-width stat pages)
// ============================================================
// ============================================================
$(function () {
$(function () {
     // Target the wide game records table on season/tournament pages
     // Skip on full-width stat pages
    if (isMccFullwidth()) return;
 
     var $table = $('.wikitable.wide-table').first();
     var $table = $('.wikitable.wide-table').first();
     if (!$table.length) $table = $('.wikitable.full-width').first();
     if (!$table.length) $table = $('.wikitable.full-width').first();
     if (!$table.length) return;
     if (!$table.length) return;


    // Collect rows (with or without tbody)
     var $rows = $table.find('tr').filter(function () {
     var $rows = $table.find('tr').filter(function () {
         return $(this).find('td').length > 0;
         return $(this).find('td').length > 0;
Рядок 795: Рядок 815:
     $rows.each(function () {
     $rows.each(function () {
         var tds = $(this).find('td');
         var tds = $(this).find('td');
        // Result is second-to-last td (before the record button)
         var r = tds.eq(tds.length - 2).text().trim();
         var r = tds.eq(tds.length - 2).text().trim();
         if (r && results.indexOf(r) === -1) results.push(r);
         if (r && results.indexOf(r) === -1) results.push(r);
     });
     });


    // Build filter bar
     var resOpts = '<option value="">Всі результати</option>';
     var resOpts = '<option value="">Всі результати</option>';
     results.forEach(function (r) {
     results.forEach(function (r) {
Рядок 823: Рядок 841:
     );
     );


    // Insert before the table's scroll wrapper (or table itself)
     var $target = $table.closest('.mcc-scroll-outer, .mcc-scroll-inner');
     var $target = $table.closest('.mcc-scroll-outer, .mcc-scroll-inner');
     ($target.length ? $target : $table).before($bar);
     ($target.length ? $target : $table).before($bar);
Рядок 857: Рядок 874:
         doFilter();
         doFilter();
     });
     });
     $bar.find('.sg-res').on('change', doFilter);
     $bar.find('.sg-res').on('change', doFilter);
     $bar.find('.sg-cnt').text($rows.length + '\u00a0ігор');
     $bar.find('.sg-cnt').text($rows.length + '\u00a0ігор');
Рядок 863: Рядок 879:
});
});


// ============================================================
// PLAYER GAMES FILTERS — pre-rendered tab (server-side FetchData)
// Runs on page load when #tab-games already has a table
// ============================================================
$(function () {
    var $content = $('#tab-games');
    if (!$content.length) return;
    // Table is pre-rendered by FetchData server-side
    var $table = $content.find('table').first();
    if (!$table.length) return;
    // Apply styles to pre-rendered table
    applyWinrateColors($content);
    applyRolePills($content);
    // Inject filters
    buildGamesFilters($content, $table);
});
// ============================================================
// SEASON RATING TABLE — medals + column colors
// Detects tables with headers: № | name | Σ | І | %
// Adds .mcc-rating-table class, then processes columns
// ============================================================
$(function () {
    function processRatingTable($t) {
        // Collect header texts
        var headers = [];
        $t.find('tr').first().find('th').each(function () {
            headers.push($(this).text().trim());
        });
        // Must start with № and have Σ at index 2
        if (headers[0] !== '№') return;
        if (headers.length < 4) return;
        // At least one of Σ, І, % must be present
        var hasSigma = headers[2] === 'Σ';
        if (!hasSigma) return;
        var iGames = 3; // І
        var iPct  = 4; // %
        var hasI  = headers[iGames] === 'І';
        var hasPct = headers[iPct]  === '%';
        // Mark table
        $t.addClass('mcc-rating-table');
        var $rows = $t.find('tbody tr').filter(function () {
            return $(this).find('td').length >= 4;
        });
        if (!$rows.length) return;
        // 1. Medal badges — top 3
        $rows.each(function () {
            var $tds = $(this).find('td');
            var n = parseInt($tds.eq(0).text().trim());
            if (n >= 1 && n <= 3) {
                $tds.eq(0).html('<span class="mcc-rank-' + n + '">' + n + '</span>');
            }
        });
        // 2. Σ white — done via CSS .mcc-rating-table td:nth-child(3)
        // 3. Games (І) — max green, min red
        if (hasI) {
            var gVals = [];
            $rows.each(function () {
                var v = parseInt($(this).find('td').eq(iGames).text().trim());
                if (!isNaN(v) && v > 0) gVals.push(v);
            });
            if (gVals.length > 1) {
                var gMax = Math.max.apply(null, gVals);
                var gMin = Math.min.apply(null, gVals);
                $rows.each(function () {
                    var $td = $(this).find('td').eq(iGames);
                    var v = parseInt($td.text().trim());
                    if (isNaN(v)) return;
                    if (v === gMax) $td.addClass('mcc-games-hi');
                    else if (v === gMin) $td.addClass('mcc-games-lo');
                });
            }
        }
        // 4. WR (%) — max green, min red
        if (hasPct) {
            var pVals = [];
            $rows.each(function () {
                var v = parseFloat($(this).find('td').eq(iPct).text().trim().replace('%',''));
                if (!isNaN(v)) pVals.push(v);
            });
            if (pVals.length > 1) {
                var pMax = Math.max.apply(null, pVals);
                var pMin = Math.min.apply(null, pVals);
                $rows.each(function () {
                    var $td = $(this).find('td').eq(iPct);
                    var v = parseFloat($td.text().trim().replace('%',''));
                    if (isNaN(v)) return;
                    if (v === pMax) $td.addClass('mcc-wr-hi');
                    else if (v === pMin) $td.addClass('mcc-wr-lo');
                });
            }
        }
    }
    // Run on all wikitables
    $('.content .mw-parser-output .wikitable').each(function () {
        processRatingTable($(this));
    });
});
// ============================================================
// ПЕРІОД TABLE — medals for top 3 (has №, PLAYERS/Гравець, Σ cols)
// ============================================================
$(function () {
    // Detect Період-style table: № | name | Σ | many season cols
    // Headers[0]='№', headers[1]='PLAYERS' or 'Гравець', headers[2]='Σ' or 'І'
    $('.content .mw-parser-output .wikitable').each(function () {
        var $t = $(this);
        if ($t.hasClass('mcc-rating-table')) return; // already processed
        var $headerRow = $t.find('tr').first();
        var $ths = $headerRow.find('th');
        if (!$ths.length) return;
        var h0 = $ths.eq(0).text().trim();
        var h1 = $ths.eq(1).text().trim();
        // Період / Статистика / Фіналіст pattern: № + name + many cols
        var isWideRank = h0 === '№' && $ths.length > 5;
        if (!isWideRank) return;
        var $rows = $t.find('tbody tr').filter(function () {
            return $(this).find('td').length >= 2;
        });
        if (!$rows.length) return;
        // Add medals for top 3
        $rows.each(function () {
            var $tds = $(this).find('td');
            var raw = $tds.eq(0).text().trim();
            var n = parseInt(raw);
            if (isNaN(n) || n < 1 || n > 3) return;
            $tds.eq(0).html('<span class="mcc-rank-' + n + '">' + n + '</span>');
        });
    });
});
// ============================================================
// SEASON FINAL TABLE — add .mcc-final-table + row numbering
// Detects: Пан/Пані | І | П | ДБ | Дія | Σ (no № column)
// ============================================================
$(function () {
    $('.content .mw-parser-output .wikitable').each(function () {
        var $t = $(this);
        if ($t.hasClass('mcc-rating-table')) return;
        var $ths = $t.find('tr').first().find('th');
        if (!$ths.length) return;
        var h0 = $ths.eq(0).text().trim();
        var h1 = $ths.eq(1).text().trim();
        var h_last = $ths.last().text().trim();
        // Final table: Пан/Пані | І | П | ДБ | Дія | Σ
        var isFinal = (h0 === 'Пан/Пані' || h0 === 'Пан' || h0 === 'Гравець')
                  && (h1 === 'І' || h1 === 'Ігри')
                  && (h_last === 'Σ');
        if (!isFinal) return;
        $t.addClass('mcc-final-table');
        // Prepend № header
        $t.find('tr').first().prepend('<th style="width:36px;text-align:center">#</th>');
        // Number each data row
        var n = 1;
        $t.find('tbody tr').each(function () {
            var $tds = $(this).find('td');
            if (!$tds.length) return;
            var prefix = '';
            if (n === 1) prefix = '<span class="mcc-rank-1">1</span>';
            else if (n === 2) prefix = '<span class="mcc-rank-2">2</span>';
            else if (n === 3) prefix = '<span class="mcc-rank-3">3</span>';
            else prefix = n;
            $(this).prepend('<td style="text-align:center;padding:10px 8px">' + prefix + '</td>');
            n++;
        });
    });
});


// ============================================================
// ============================================================
// 17. BANNER SEARCH
// 17. BANNER SEARCH