MediaWiki:Gadget-TimelinePreview.js
From Angelina Jordan Wiki
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.
// Gadget: Timeline hover previews (integrated with system popups)
// Requires: mediawiki.api, jquery, mediawiki.util
mw.loader.using(['mediawiki.api', 'jquery', 'mediawiki.util']).then(function () {
var api = new mw.Api();
var timelineCache = null;
function capitalizeFirst(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
function loadTimeline() {
if (timelineCache) return $.Deferred().resolve();
return api.get({
action: 'parse',
page: 'Timeline',
prop: 'text',
formatversion: 2
}).then(function (data) {
var html = $('<div>').html(data.parse.text);
timelineCache = {};
html.find('dt').each(function () {
var dt = $(this);
var id = dt.find('span[id]').attr('id');
if (!id) return;
var ddList = [];
var el = dt.next();
while (el.length && el.prop('tagName') === 'DD') {
var clone = el.clone();
// Remove references
clone.find('sup.reference').remove();
// Strip links
clone.find('a').replaceWith(function () {
return $(this).text();
});
ddList.push(clone.html());
el = el.next();
}
// Join, capitalize first letter
if (ddList.length) {
var text = ddList.join('<br>').trim();
timelineCache[id] = capitalizeFirst(text);
}
});
});
}
function showTimelineInSystemPopup($link, id) {
if (!timelineCache || !timelineCache[id]) return;
// Poll for system popup
var attempts = 0;
var maxAttempts = 20;
var interval = 50; // ms
var timer = setInterval(function () {
attempts++;
var popup = $link.data('mwePopups'); // MW page preview reference
if (popup && popup.$content && popup.$content.length) {
// Inject Timeline content inside with small padding
popup.$content.html(
$('<div>')
.css({ padding: '0.5em' })
.html(timelineCache[id])
);
clearInterval(timer);
} else if (attempts >= maxAttempts) {
// fallback: show nothing
clearInterval(timer);
}
}, interval);
}
function onHover() {
var $link = $(this);
var href = $link.attr('href') || '';
var match =
href.match(/\/Timeline#(\d{4}-\d{2}-\d{2})$/) ||
href.match(/^#(\d{4}-\d{2}-\d{2})$/);
if (!match) return;
var id = match[1];
loadTimeline().then(function () {
showTimelineInSystemPopup($link, id);
});
}
function bindTimelineLinks(context) {
$(context)
.find('a[href*="Timeline#"], a[href^="#"]')
.each(function () {
var $link = $(this);
var href = $link.attr('href') || '';
if (
href.match(/Timeline#\d{4}-\d{2}-\d{2}$/) ||
href.match(/^#\d{4}-\d{2}-\d{2}$/)
) {
// Attach hover handler
$link.off('.timelinePreview')
.on('mouseenter.timelinePreview', onHover);
}
});
}
// Initial bind
mw.hook('wikipage.content').add(bindTimelineLinks);
// Observe dynamically revealed nodes (collapsed sections)
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (m) {
Array.from(m.addedNodes).forEach(function (node) {
if (node.nodeType === 1) bindTimelineLinks(node);
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
});