MediaWiki:Common.js: Difference between revisions
Appearance
Buildababe (talk | contribs) No edit summary Tags: Manual revert Mobile edit Mobile web edit |
Buildababe (talk | contribs) No edit summary Tags: Mobile edit Mobile web edit |
||
| Line 297: | Line 297: | ||
}() ); | }() ); | ||
// Animate rainbow portrait rings | |||
mw.hook('wikipage.content').add(function() { | |||
document.querySelectorAll('[data-portrait-border="rainbow"]').forEach(function(el) { | |||
el.classList.add('pb-rainbow-ring'); | |||
}); | |||
}); | |||
Latest revision as of 16:34, 11 April 2026
// Adds a search box that filters category members in real time
if (document.querySelector('.mw-category')) {
const input = document.createElement('input');
input.placeholder = 'Filter pages...';
input.style.cssText = `
display: block; margin: 12px 0; padding: 8px 16px;
border: 2px solid #b3e5fc; border-radius: 20px;
font-family: Nunito, sans-serif; font-size: 1em; width: 300px;
`;
document.querySelector('.mw-category').before(input);
input.addEventListener('input', () => {
document.querySelectorAll('.mw-category li').forEach(li => {
li.style.display = li.textContent.toLowerCase()
.includes(input.value.toLowerCase()) ? '' : 'none';
});
});
}
/* ============================================================
WIKI COMMON.JS — Bundled Scripts
Paste into Special:EditPage/MediaWiki:Common.js
============================================================ */
( function () {
'use strict';
/* ----------------------------------------------------------
1. RANDOM WELCOME MESSAGE on the main page
---------------------------------------------------------- */
var greetings = [
"Welcome to the show! 🎪",
"Step right up! 🎠",
"The circus is in town! 🎡",
"Tonight's performance begins now! 🎭",
];
var subtitleEl = document.querySelector('.circus-subtitle');
if (subtitleEl) {
subtitleEl.textContent = greetings[Math.floor(Math.random() * greetings.length)];
}
/* ----------------------------------------------------------
2. CARDS CYCLE THROUGH COLORS on hover
---------------------------------------------------------- */
var cardColors = ['#29b6f6','#f06292','#ab47bc','#66bb6a','#ffa726'];
document.querySelectorAll('.circus-card').forEach(function (card) {
card.addEventListener('mouseenter', function () {
var c = cardColors[Math.floor(Math.random() * cardColors.length)];
card.style.borderColor = c;
var icon = card.querySelector('.circus-card-icon');
if (icon) icon.style.color = c;
});
card.addEventListener('mouseleave', function () {
card.style.borderColor = '';
var icon = card.querySelector('.circus-card-icon');
if (icon) icon.style.color = '';
});
});
/* ----------------------------------------------------------
3. LOGO SPIN on click
---------------------------------------------------------- */
var logo = document.querySelector('.circus-logo-inner');
if (logo) {
logo.style.transition = 'transform 0.6s cubic-bezier(0.34,1.56,0.64,1)';
logo.style.cursor = 'pointer';
logo.addEventListener('click', function () {
logo.style.transform = 'rotate(360deg) scale(1.2)';
setTimeout(function () { logo.style.transform = ''; }, 600);
});
}
/* ----------------------------------------------------------
4. TYPEWRITER EFFECT on wiki subtitle
---------------------------------------------------------- */
var typeEl = document.querySelector('.circus-subtitle');
if (typeEl) {
var fullText = typeEl.textContent;
typeEl.textContent = '';
var i = 0;
var type = function () {
if (i < fullText.length) {
typeEl.textContent += fullText[i++];
setTimeout(type, 40);
}
};
type();
}
/* ----------------------------------------------------------
5. DARK MODE TOGGLE button (bottom-right)
---------------------------------------------------------- */
var darkBtn = document.createElement('button');
darkBtn.title = 'Toggle dark mode';
darkBtn.style.cssText = [
'position:fixed','top:90px','right:16px',
'width:40px','height:40px','border-radius:50%',
'border:2px solid #b3e5fc','background:#f0f8ff',
'font-size:18px','cursor:pointer','z-index:9999',
'display:flex','align-items:center','justify-content:center'
].join(';');
document.body.appendChild(darkBtn);
var darkCSS = [
'html,body,#content,.mw-body,.mw-page-container,',
'#mw-panel,.vector-menu-portal,#mw-head{',
'background-color:#0d1b2a!important;color:#cde8f6!important}',
'.circus-card{background:#122336!important;border-color:#1e4060!important}',
'.circus-title{color:#4fc3f7!important}',
'a{color:#4fc3f7!important}'
].join('');
var darkStyle = document.createElement('style');
document.head.appendChild(darkStyle);
function applyDark(on) {
darkStyle.textContent = on ? darkCSS : '';
darkBtn.textContent = on ? '☀️' : '🌙';
}
darkBtn.addEventListener('click', function () {
var isDark = localStorage.getItem('wikiDarkMode') === '1';
localStorage.setItem('wikiDarkMode', isDark ? '0' : '1');
applyDark(!isDark);
});
applyDark(localStorage.getItem('wikiDarkMode') === '1');
/* ----------------------------------------------------------
6. WORD COUNT on article pages
---------------------------------------------------------- */
var contentArea = document.querySelector('#mw-content-text');
var isEditing = document.querySelector('.action-edit, .action-submit');
if (contentArea && !isEditing) {
var words = contentArea.innerText.trim().split(/\s+/).length;
var wordBar = document.createElement('div');
wordBar.style.cssText = 'font-family:Nunito,sans-serif;font-size:0.85em;color:#4a7a9e;margin-bottom:12px;';
wordBar.textContent = '📄 ' + words.toLocaleString() + ' words';
contentArea.prepend(wordBar);
}
/* ----------------------------------------------------------
7. "LAST EDITED X AGO" in the footer
---------------------------------------------------------- */
var lastMod = document.querySelector('#footer-info-lastmod');
if (lastMod) {
var match = lastMod.textContent.match(/(\d{1,2} \w+ \d{4})/);
if (match) {
var edited = new Date(match[1]);
var mins = Math.floor((Date.now() - edited) / 60000);
var ago = mins < 60
? mins + ' minutes ago'
: mins < 1440
? Math.floor(mins / 60) + ' hours ago'
: Math.floor(mins / 1440) + ' days ago';
lastMod.textContent += ' (' + ago + ')';
}
}
/* ----------------------------------------------------------
8. HIGHLIGHT RED LINKS with a tooltip
---------------------------------------------------------- */
document.querySelectorAll('a.new').forEach(function (link) {
link.title = '⚠️ This page does not exist yet — click to create it!';
link.style.cssText = 'background:#fff0f3;border-radius:4px;padding:1px 4px;text-decoration:none!important;';
});
/* ----------------------------------------------------------
9. COPY BUTTON on code blocks
---------------------------------------------------------- */
document.querySelectorAll('pre').forEach(function (pre) {
var copyBtn = document.createElement('button');
copyBtn.textContent = 'Copy';
copyBtn.style.cssText = [
'float:right','padding:2px 10px','font-size:0.8em',
'border:2px solid #b3e5fc','border-radius:10px',
'background:#f0f8ff','cursor:pointer',
'font-family:Nunito,sans-serif'
].join(';');
copyBtn.addEventListener('click', function () {
navigator.clipboard.writeText(pre.innerText).then(function () {
copyBtn.textContent = 'Copied!';
setTimeout(function () { copyBtn.textContent = 'Copy'; }, 2000);
});
});
pre.prepend(copyBtn);
});
/* ----------------------------------------------------------
10. PRESS "/" TO FOCUS SEARCH
---------------------------------------------------------- */
document.addEventListener('keydown', function (e) {
var tag = document.activeElement.tagName;
if (e.key === '/' && tag !== 'INPUT' && tag !== 'TEXTAREA') {
e.preventDefault();
var searchBox = document.querySelector('#searchInput, .vector-search-box input');
if (searchBox) searchBox.focus();
}
});
/* ----------------------------------------------------------
11. STICKY TOC — highlights current section while scrolling
---------------------------------------------------------- */
var toc = document.querySelector('#toc');
var headings = document.querySelectorAll('h2, h3');
if (toc && headings.length) {
window.addEventListener('scroll', function () {
var current = '';
headings.forEach(function (h) {
if (window.scrollY >= h.offsetTop - 100) current = h.id;
});
toc.querySelectorAll('a').forEach(function (a) {
var active = a.href.includes(current) && current !== '';
a.style.color = active ? '#0288d1' : '';
a.style.fontWeight = active ? '900' : '';
});
});
}
/* ----------------------------------------------------------
12. RANDOM ARTICLE BUTTON on main page
---------------------------------------------------------- */
var heroEl = document.querySelector('.circus-hero');
var isMainPage = document.title.toLowerCase().includes('main');
if (heroEl && isMainPage) {
var randBtn = document.createElement('a');
randBtn.href = '/wiki/Special:Random';
randBtn.textContent = '🎲 Take me somewhere random!';
randBtn.style.cssText = [
'display:inline-block','margin-top:10px',
'padding:10px 24px','border-radius:24px',
'background:#29b6f6','color:white!important',
'font-family:Nunito,sans-serif','font-weight:700',
'font-size:1em','text-decoration:none!important',
'transition:transform 0.2s'
].join(';');
randBtn.addEventListener('mouseenter', function () { randBtn.style.transform = 'scale(1.05)'; });
randBtn.addEventListener('mouseleave', function () { randBtn.style.transform = ''; });
heroEl.appendChild(randBtn);
}
/* ----------------------------------------------------------
13. COLOR-CODED CATEGORY TAGS
---------------------------------------------------------- */
var catPalette = [
'#29b6f6','#f06292','#ab47bc','#66bb6a',
'#ffa726','#ef5350','#26c6da','#d4e157'
];
document.querySelectorAll('#catlinks a').forEach(function (a) {
var idx = a.textContent.charCodeAt(0) % catPalette.length;
var c = catPalette[idx];
a.style.cssText = [
'background:' + c + '22',
'color:' + c,
'border:1.5px solid ' + c + '66',
'border-radius:12px',
'padding:2px 10px',
'margin:2px',
'display:inline-block',
'font-weight:700',
'text-decoration:none!important'
].join(';');
});
/* ----------------------------------------------------------
14. LIVE SEARCH FILTER on category pages
---------------------------------------------------------- */
var catSection = document.querySelector('.mw-category');
if (catSection) {
var filterInput = document.createElement('input');
filterInput.placeholder = '🔍 Filter pages...';
filterInput.style.cssText = [
'display:block','margin:12px 0','padding:8px 16px',
'border:2px solid #b3e5fc','border-radius:20px',
'font-family:Nunito,sans-serif','font-size:1em','width:300px'
].join(';');
catSection.before(filterInput);
filterInput.addEventListener('input', function () {
var val = filterInput.value.toLowerCase();
document.querySelectorAll('.mw-category li').forEach(function (li) {
li.style.display = li.textContent.toLowerCase().includes(val) ? '' : 'none';
});
});
}
}() );
// Animate rainbow portrait rings
mw.hook('wikipage.content').add(function() {
document.querySelectorAll('[data-portrait-border="rainbow"]').forEach(function(el) {
el.classList.add('pb-rainbow-ring');
});
});