Увага: Після публікування слід очистити кеш браузера, щоб побачити зміни.
- Firefox / Safari: тримайте Shift, коли натискаєте Оновити, або натисніть Ctrl-F5 чи Ctrl-Shift-R (⌘-R на Apple Mac)
- Google Chrome: натисніть Ctrl-Shift-R (⌘-Shift-R на Apple Mac)
- Internet Explorer / Edge: тримайте Ctrl, коли натискаєте Оновити, або натисніть Ctrl-F5
- Opera: натисніть Ctrl-F5
// ============================================================
// MediaWiki:Common.js — Mafia Closed Circle
// Фінальна версія
// ============================================================
// ============================================================
// 1. RANDOM ARTICLES
// ============================================================
$(document).ready(function () {
var apiUrl = mw.config.get('wgScriptPath') + '/api.php';
$.getJSON(apiUrl, {
action: 'query', format: 'json', list: 'random',
rnnamespace: '0', rnlimit: '5',
prop: 'extracts', exchars: '250', exlimit: 'max', explaintext: true
}, function (data) {
var html = '';
$.each(data.query.random, function (i, article) {
html += '<div class="random-article-preview">';
html += '<h2><a href="/wiki/' + encodeURIComponent(article.title) + '">' + article.title + '</a></h2>';
html += '</div>';
});
$('#random-articles-container').html(html);
});
});
// ============================================================
// 2. L-BOX NAVIGATION
// ============================================================
$(function () {
var $lbox = $('.l-box');
if ($lbox.length === 0) return;
var $items = $lbox.find('.l-box-item');
function buildSectionMap() {
var map = [];
$items.each(function () {
var target = $(this).data('target');
if (target === 'top') {
map.push({ $item: $(this), top: 0 });
} else {
var $el = $('#' + target);
if ($el.length) {
map.push({ $item: $(this), top: $el.offset().top });
}
}
});
map.sort(function (a, b) { return a.top - b.top; });
return map;
}
function updateActive(map) {
var scrollY = $(window).scrollTop() + 110;
var current = null;
for (var i = 0; i < map.length; i++) {
if (map[i].top <= scrollY) current = map[i].$item;
}
$items.removeClass('active');
if (current) current.addClass('active');
}
$items.on('click', function () {
var target = $(this).data('target');
if (target === 'top') {
$('html, body').animate({ scrollTop: 0 }, 280);
} else {
var $el = $('#' + target);
if ($el.length) {
$('html, body').animate({ scrollTop: $el.offset().top - 75 }, 280);
}
}
});
var sectionMap = buildSectionMap();
$(document).on('mcc:content-loaded', function () {
sectionMap = buildSectionMap();
updateActive(sectionMap);
});
var ticking = false;
$(window).on('scroll', function () {
if (!ticking) {
window.requestAnimationFrame(function () {
updateActive(sectionMap);
ticking = false;
});
ticking = true;
}
});
$(window).on('resize', function () {
sectionMap = buildSectionMap();
updateActive(sectionMap);
});
updateActive(sectionMap);
});
// ============================================================
// 3. PROFILE ICONS — клік + inactive якщо немає URL
// ============================================================
$(document).ready(function () {
$('.profile-icon').each(function () {
var $icon = $(this);
var url = ($icon.attr('data-url') || '').trim();
if (url) {
$icon.css('cursor', 'pointer');
$icon.on('click', function () {
window.open(url, '_blank');
});
} else {
$icon.addClass('inactive');
}
});
});
// ============================================================
// 4. ДИНАМІЧНІ ПОСИЛАННЯ НА ГОЛОВНІЙ
// ============================================================
$(document).ready(function () {
if (!$('body').hasClass('page-Головна_сторінка')) return;
var block1Links = [{ title: 'Фінал Року', url: '/index.php/Фінал_Року' }];
var block2Links = [
{ title: 'Перша статистика', url: '/index.php/Перша_статистика' },
{ title: 'Період', url: '/index.php/Період' },
{ title: 'Друга статистика', url: '/index.php/Статистика' }
];
var block3Links = [
{ title: 'Mafia Closed Cup I', url: '/index.php/Mafia_Closed_Cup_I' },
{ title: 'Mafia Closed Cup I Online', url: '/index.php/Mafia_Closed_Cup_I_Online' },
{ title: 'My Closest Circle I', url: '/index.php/My_Closest_Circle_I' }
];
function rand(arr) { return arr[Math.floor(Math.random() * arr.length)]; }
var $blocks = $('.home__block-image-block p');
if ($blocks.length >= 3) {
var l1 = rand(block1Links), l2 = rand(block2Links), l3 = rand(block3Links);
$blocks.eq(0).html('<a href="' + l1.url + '">' + l1.title + '</a>');
$blocks.eq(1).html('<a href="' + l2.url + '">' + l2.title + '</a>');
$blocks.eq(2).html('<a href="' + l3.url + '">' + l3.title + '</a>');
}
});
// ============================================================
// 5. PLAYER TABS + LAZY LOADING ІГОР
// ============================================================
$(function () {
var $tabs = $('.player-tab');
var $contents = $('.player-tab-content');
var $lbox = $('.l-box');
var $rbox = $('.r-box');
if ($tabs.length === 0) return;
function isMobile() { return $(window).width() <= 768; }
$tabs.on('click', function () {
var $tab = $(this);
var tabId = $tab.data('tab');
var $content = $('#tab-' + tabId);
$tabs.removeClass('active');
$tab.addClass('active');
$contents.removeClass('active');
$content.addClass('active');
// L-box — ховаємо на вкладці ігор
if (tabId === 'games') {
$lbox.fadeOut(200);
} else {
$lbox.fadeIn(200);
}
// R-box — на мобільних ховаємо при іграх
if (isMobile()) {
if (tabId === 'games') $rbox.slideUp(200);
else $rbox.slideDown(200);
}
// Lazy load
if (tabId === 'games' && !$content.data('loaded')) {
var playerName = $content.data('player');
if (!playerName) return;
$content.html('<div class="tab-loader">Завантаження...</div>');
$.ajax({
url: mw.config.get('wgScriptPath') + '/api.php',
data: {
action: 'expandtemplates', format: 'json',
text: '{{#invoke:FetchData|player_games|player=' + playerName + '}}',
prop: 'wikitext'
},
dataType: 'json',
success: function (response) {
if (!response.expandtemplates || !response.expandtemplates.wikitext) return;
$.ajax({
url: mw.config.get('wgScriptPath') + '/api.php',
data: {
action: 'parse', format: 'json',
text: response.expandtemplates.wikitext,
contentmodel: 'wikitext',
disablelimitreport: true
},
dataType: 'json',
success: function (r) {
if (r.parse && r.parse.text) {
$content.html(r.parse.text['*']);
$content.data('loaded', true);
$content.find('table.sortable').tablesorter();
// Запускаємо пост-обробку для нового контенту
applyWinrateColors($content);
wrapWideTables($content);
$(document).trigger('mcc:content-loaded');
}
},
error: function () {
$content.html('<p style="color:#ff7777;text-align:center">Помилка завантаження.</p>');
}
});
},
error: function () {
$content.html('<p style="color:#ff7777;text-align:center">Помилка завантаження.</p>');
}
});
}
});
$(window).on('resize', function () {
if (!isMobile()) $rbox.show();
});
});
// ============================================================
// 6. АНІМАЦІЯ РЯДКІВ ПРИ СОРТУВАННІ
// ============================================================
$(function () {
$(document).on('sortEnd', 'table.wikitable', function () {
var $t = $(this);
$t.addClass('mcc-sorting').removeClass('mcc-sorted');
setTimeout(function () {
$t.removeClass('mcc-sorting').addClass('mcc-sorted');
setTimeout(function () { $t.removeClass('mcc-sorted'); }, 600);
}, 20);
});
});
// ============================================================
// 7. ГОРИЗОНТАЛЬНИЙ СКРОЛ ДЛЯ ШИРОКИХ ТАБЛИЦЬ
// ============================================================
function wrapWideTables($context) {
var $root = $context || $(document);
function wrap($table) {
if ($table.closest('.mcc-scroll-inner').length) return;
$table.wrap('<div class="mcc-scroll-inner"></div>');
$table.closest('.mcc-scroll-inner').wrap('<div class="mcc-scroll-outer"></div>');
var $inner = $table.closest('.mcc-scroll-inner');
var $outer = $inner.closest('.mcc-scroll-outer');
function check() {
var atEnd = $inner[0].scrollLeft + $inner[0].clientWidth >= $inner[0].scrollWidth - 4;
$outer.toggleClass('mcc-no-fade', atEnd);
}
$inner.on('scroll', check);
check();
}
// Явно задані широкі класи
$root.find('.wikitable.wide-table, .wikitable.mcc-wide, .wikitable.full-width').each(function () {
wrap($(this));
});
// Таблиці з >8 колонок (Запис ігор)
$root.find('.wikitable').each(function () {
var $t = $(this);
if ($t.closest('.mcc-scroll-inner').length) return;
if ($t.find('thead tr:first th').length > 8) {
$t.addClass('mcc-wide-table');
wrap($t);
}
});
}
$(function () { wrapWideTables(); });
// ============================================================
// 8. ВІНРЕЙТ — кольорове підсвічення клітинок з %
// ============================================================
function applyWinrateColors($context) {
var $root = $context || $(document);
$root.find('.wikitable tbody td').each(function () {
var text = $(this).text().trim();
if (/^\d+(\.\d+)?%$/.test(text)) {
var val = parseFloat(text);
if (val >= 55) $(this).addClass('wr-hi');
else if (val <= 33) $(this).addClass('wr-lo');
}
});
}
$(function () { applyWinrateColors(); });
// ============================================================
// 9. МОБІЛЬНИЙ ПОШУК
// ============================================================
$(function () {
if ($(window).width() > 768) return;
if ($('.mobile-search-btn').length > 0) return;
var $btn = $('<div class="mobile-search-btn">' +
'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2">' +
'<circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg></div>');
var $overlay = $('<div class="mobile-search-overlay">' +
'<input type="text" placeholder="Пошук..." autocomplete="off">' +
'<div class="mobile-search-close">×</div></div>');
$('.minerva-header .branding-box').after($btn);
$('body').append($overlay);
var $input = $overlay.find('input');
var $close = $overlay.find('.mobile-search-close');
$btn.on('click', function (e) {
e.preventDefault(); e.stopPropagation();
$overlay.addClass('active');
setTimeout(function () { $input.focus(); }, 100);
});
$close.on('click', function () {
$overlay.removeClass('active'); $input.val('');
});
$input.on('keydown', function (e) {
if (e.keyCode === 13) {
var q = $input.val().trim();
if (q) window.location.href = '/index.php?title=Спеціальна:Пошук&search=' + encodeURIComponent(q);
}
if (e.keyCode === 27) { $overlay.removeClass('active'); $input.val(''); }
});
$overlay.on('click', function (e) {
if (e.target === this) { $overlay.removeClass('active'); $input.val(''); }
});
});
// ============================================================
// 10. БЛОКУВАННЯ MINERVA SEARCH OVERLAY (ДЕСКТОП)
// ============================================================
$(function () {
if ($(window).width() <= 768) return;
var $searchInput = $('#searchInput');
if ($searchInput.length === 0) return;
setTimeout(function () {
$searchInput.attr('placeholder', 'Пошук...');
var $newInput = $searchInput.clone(false);
$searchInput.replaceWith($newInput);
$searchInput = $newInput;
$searchInput.prop('readonly', false).removeAttr('readonly')
.removeClass('skin-minerva-search-trigger');
$searchInput.on('focus click', function (e) {
e.stopPropagation();
$('body').removeClass('overlay-enabled search-enabled');
$('.overlay, .search-overlay').hide();
if (window.location.hash === '#/search') {
history.replaceState(null, null, window.location.pathname);
}
});
$searchInput.on('keydown', function (e) {
if (e.which === 13) {
e.preventDefault();
var q = $(this).val().trim();
if (q) window.location.href = '/index.php?title=Спеціальна:Пошук&search=' + encodeURIComponent(q);
return false;
}
});
}, 100);
$(window).on('hashchange', function () {
if (window.location.hash === '#/search') {
history.replaceState(null, null, window.location.pathname);
$('body').removeClass('overlay-enabled search-enabled');
$('.overlay, .search-overlay').hide();
}
});
if (window.location.hash === '#/search') {
history.replaceState(null, null, window.location.pathname);
}
});
// ============================================================
// 11. BANNER SEARCH
// ============================================================
$(function () {
var $container = $('#bannerSearchContainer');
if ($container.length === 0) return;
var $input = $('<input>', { type: 'text', id: 'bannerSearchInput', placeholder: 'Пошук MCC...' });
var $btn = $('<button>', { id: 'bannerSearchBtn', text: 'Пошук' });
$container.append($input).append($btn);
function doSearch() {
var q = $input.val().trim();
if (q) window.location.href = '/index.php?title=Спеціальна:Пошук&search=' + encodeURIComponent(q);
}
$btn.on('click', doSearch);
$input.on('keydown', function (e) { if (e.keyCode === 13) { e.preventDefault(); doSearch(); } });
});