MediaWiki:Common.js: Difference between revisions
Appearance
Sonja says (talk | contribs) No edit summary |
Sonja says (talk | contribs) No edit summary |
||
| Line 50: | Line 50: | ||
icons.prepend(link); // use appendChild() if you want it at the end | icons.prepend(link); // use appendChild() if you want it at the end | ||
}); | |||
// =============================== | |||
// Sticky Header Countdown Timer (Vector 2022) - to Apr 18, 2026 00:00 UTC | |||
// =============================== | |||
mw.hook('wikipage.content').add(function () { | |||
const icons = document.querySelector('.vector-sticky-header-icons'); | |||
if (!icons) return; | |||
// Prevent duplicates | |||
if (document.getElementById('sticky-countdown')) return; | |||
// Target: Sat, 18 Apr 2026 at 00:00 GMT+00:00 (UTC) | |||
const target = new Date('2026-04-18T00:00:00Z'); | |||
const wrap = document.createElement('span'); | |||
wrap.id = 'sticky-countdown'; | |||
wrap.className = 'sticky-countdown'; | |||
const label = document.createElement('span'); | |||
label.className = 'sticky-countdown__label'; | |||
label.textContent = 'Ends in:'; | |||
const value = document.createElement('span'); | |||
value.className = 'sticky-countdown__value'; | |||
value.textContent = '--:--:--'; | |||
wrap.appendChild(label); | |||
wrap.appendChild(value); | |||
// Put it before the default icons (Talk/History/Edit) | |||
icons.prepend(wrap); | |||
const pad = (n) => String(n).padStart(2, '0'); | |||
const formatRemaining = (ms) => { | |||
if (ms <= 0) return '00:00:00'; | |||
const totalSeconds = Math.floor(ms / 1000); | |||
const days = Math.floor(totalSeconds / 86400); | |||
const hours = Math.floor((totalSeconds % 86400) / 3600); | |||
const minutes = Math.floor((totalSeconds % 3600) / 60); | |||
const seconds = totalSeconds % 60; | |||
if (days > 0) return `${days}d ${pad(hours)}:${pad(minutes)}:${pad(seconds)}`; | |||
return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`; | |||
}; | |||
const update = () => { | |||
const now = new Date(); | |||
const diff = target.getTime() - now.getTime(); | |||
value.textContent = formatRemaining(diff); | |||
wrap.classList.toggle('is-expired', diff <= 0); | |||
}; | |||
update(); | |||
const timerId = window.setInterval(update, 1000); | |||
// Cleanup if element removed (rare, but safe) | |||
const observer = new MutationObserver(() => { | |||
if (!document.getElementById('sticky-countdown')) { | |||
clearInterval(timerId); | |||
observer.disconnect(); | |||
} | |||
}); | |||
observer.observe(document.body, { childList: true, subtree: true }); | |||
}); | }); | ||
Revision as of 13:17, 13 February 2026
/* Any JavaScript here will be loaded for all users on every page load. */
// Tab functionality
$(document).ready(function() {
// Initialize tabs - show first tab by default
$('.wiki-tabs-container').each(function() {
var $container = $(this);
var $firstButton = $container.find('.wiki-tab-button').first();
var firstTabId = $firstButton.data('tab');
$firstButton.addClass('active');
$container.find('#' + firstTabId).addClass('active').show();
});
// Tab click handler
$('.wiki-tab-button').on('click', function() {
var $button = $(this);
var tabId = $button.data('tab');
var $container = $button.closest('.wiki-tabs-container');
// Remove active class from all buttons and panes in this container
$container.find('.wiki-tab-button').removeClass('active');
$container.find('.wiki-tab-pane').removeClass('active').hide();
// Add active class to clicked button and corresponding pane
$button.addClass('active');
$container.find('#' + tabId).addClass('active').show();
});
});
// ===============================
// Add Custom Sticky Header Link
// ===============================
mw.hook('wikipage.content').add(function () {
const icons = document.querySelector('.vector-sticky-header-icons');
if (!icons) return;
// Prevent duplicate button on navigation
if (document.getElementById('custom-sticky-link')) return;
const link = document.createElement('a');
link.id = 'custom-sticky-link';
link.href = 'https://discord.gg/t2Rp2dRvze'; // CHANGE THIS
link.target = '_blank';
link.className = 'cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet';
link.textContent = 'Join Us on Discord!'; // CHANGE TEXT
link.style.marginLeft = '10px';
link.style.fontWeight = 'bold';
icons.prepend(link); // use appendChild() if you want it at the end
});
// ===============================
// Sticky Header Countdown Timer (Vector 2022) - to Apr 18, 2026 00:00 UTC
// ===============================
mw.hook('wikipage.content').add(function () {
const icons = document.querySelector('.vector-sticky-header-icons');
if (!icons) return;
// Prevent duplicates
if (document.getElementById('sticky-countdown')) return;
// Target: Sat, 18 Apr 2026 at 00:00 GMT+00:00 (UTC)
const target = new Date('2026-04-18T00:00:00Z');
const wrap = document.createElement('span');
wrap.id = 'sticky-countdown';
wrap.className = 'sticky-countdown';
const label = document.createElement('span');
label.className = 'sticky-countdown__label';
label.textContent = 'Ends in:';
const value = document.createElement('span');
value.className = 'sticky-countdown__value';
value.textContent = '--:--:--';
wrap.appendChild(label);
wrap.appendChild(value);
// Put it before the default icons (Talk/History/Edit)
icons.prepend(wrap);
const pad = (n) => String(n).padStart(2, '0');
const formatRemaining = (ms) => {
if (ms <= 0) return '00:00:00';
const totalSeconds = Math.floor(ms / 1000);
const days = Math.floor(totalSeconds / 86400);
const hours = Math.floor((totalSeconds % 86400) / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
if (days > 0) return `${days}d ${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
};
const update = () => {
const now = new Date();
const diff = target.getTime() - now.getTime();
value.textContent = formatRemaining(diff);
wrap.classList.toggle('is-expired', diff <= 0);
};
update();
const timerId = window.setInterval(update, 1000);
// Cleanup if element removed (rare, but safe)
const observer = new MutationObserver(() => {
if (!document.getElementById('sticky-countdown')) {
clearInterval(timerId);
observer.disconnect();
}
});
observer.observe(document.body, { childList: true, subtree: true });
});