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)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// MediaWiki:Common.js
mw.loader.using('mediawiki.api').then(() => {
const api = new mw.Api();
const RC_CONTAINER = document.getElementById('RCMain');
// Simple "time ago" formatter
const timeAgo = timestamp => {
const seconds = Math.floor((Date.now() - new Date(timestamp)) / 1000);
const intervals = [
{ label: 'day', secs: 86400 },
{ label: 'hour', secs: 3600 },
{ label: 'minute', secs: 60 },
{ label: 'second', secs: 1 }
];
for (const { label, secs } of intervals) {
const count = Math.floor(seconds / secs);
if (count > 0) {
return `${count} ${label}${count > 1 ? 's' : ''}`;
}
}
return 'just now';
};
// Build one entry, prepend it, then activate
const prependChange = c => {
const entry = document.createElement('div');
entry.className = 'rc-entry';
entry.innerHTML = `
<div class="rc-line1">
<strong>${mw.html.escape(c.user)}</strong>
${c.type}
<a href="${mw.config.get('wgServer') + mw.config.get('wgScriptPath')}/index.php?title=${encodeURIComponent(c.title)}">
${mw.html.escape(c.title)}
</a>
</div>
<div class="rc-line2">
${timeAgo(c.timestamp)} ago
</div>
`;
RC_CONTAINER.insertBefore(entry, RC_CONTAINER.firstChild);
// give the browser a tick before adding the active class
setTimeout(() => {
entry.classList.add('rc-active');
}, 1);
};
// Fetch recent changes
api.get({
action: 'query',
list: 'recentchanges',
rcprop: 'title|ids|sizes|comment|user|timestamp|flags',
rclimit: 50,
rcshow: '!bot',
format: 'json'
}).then(data => {
const changes = data.query.recentchanges;
// 1. clear placeholder
RC_CONTAINER.replaceChildren();
// 2. prepend first 3 immediately
changes.slice(0, 3).forEach(prependChange);
// 3–5. every 3s prepend the next one with activation
let idx = 3;
const timer = setInterval(() => {
if (idx >= changes.length) {
clearInterval(timer);
} else {
prependChange(changes[idx++]);
}
}, 3000);
}).catch(err => {
console.error('Failed to load recent changes:', err);
RC_CONTAINER.textContent = 'Error loading recent changes.';
});
});