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.
/**
* Bharatpedia Vector main page — auto news, DYK, month events, recent deaths.
* MediaWiki 1.43. Vector / Vector 2022 only. Main page only.
*
* Same sources as BharatpediaNeo homepage.js:
* User:WikiDwarf/sandbox → .homepagecache-india-news / .homepagecache-india-dyk
* {{CURRENTYEAR}} in India → Events + Deaths
*
* Install: MediaWiki:Gadget-vector-homepage.js
* (or the bottom of MediaWiki:Vector.js)
* Gadget definition: vector-homepage[ResourceLoader|default|targets=desktop]|vector-homepage.js
*/
(function () {
if (
typeof mw === 'undefined' ||
!mw.config.get('wgIsMainPage')
) {
return;
}
var skin = mw.config.get('wgSkin') || '';
if (skin !== 'vector' && skin !== 'vector-2022') {
return;
}
var HOMEPAGECACHE_PAGE = 'User:WikiDwarf/sandbox';
var api = new mw.Api();
function $(id) {
return document.getElementById(id);
}
function localizeWikiLinks(html) {
return String(html || '')
.replace(/(?:https?:)?\/\/en\.wikipedia\.org\/wiki\//gi, '/wiki/')
.replace(/(?:https?:)?\/\/en\.wikipedia\.org\/w\/index\.php\?title=/gi, '/wiki/')
.replace(/href="\/w\/index\.php\?title=([^"&#]+)/gi, 'href="/wiki/$1');
}
function istNow() {
return new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Kolkata' }));
}
function wikiToHtml(text) {
return String(text || '')
.replace(/<ref[\s\S]*?<\/ref>/gi, '')
.replace(/<ref[^>]*\/?>/gi, '')
.replace(/\{\{[^{}]*\}\}/g, '')
.replace(/\[\[([^|\]]+)\|([^\]]+)\]\]/g, function (_, t, l) {
return '<a href="' + mw.util.getUrl(t) + '">' + l + '</a>';
})
.replace(/\[\[([^\]]+)\]\]/g, function (_, t) {
return '<a href="' + mw.util.getUrl(t) + '">' + t + '</a>';
})
.replace(/'''(.*?)'''/g, '<b>$1</b>')
.replace(/''(.*?)''/g, '<i>$1</i>')
.replace(/\s+/g, ' ')
.trim();
}
function splitNewsItems(html) {
var tmp = document.createElement('div');
tmp.innerHTML = html || '';
var parts = Array.prototype.map.call(tmp.querySelectorAll('li'), function (n) {
return n.innerHTML.trim();
}).filter(Boolean);
if (parts.length < 2) {
parts = String(html || '')
.replace(/<div class="homepagecache-meta"[^>]*>[\s\S]*$/i, '')
.replace(/Source:[\s\S]*$/i, '')
.split(/(?=\d{1,2}\s+(?:January|February|March|April|May|June|July|August|September|October|November|December)\s+\d{4})/)
.map(function (x) { return x.trim(); })
.filter(function (x) { return x.length > 30; });
}
return parts;
}
function renderSlot(el, title, html, moreHref, moreLabel) {
if (!el) {
return;
}
if (!html) {
el.innerHTML = '<p class="bp-vec-empty">Nothing cached yet.</p>';
return;
}
var wrap = document.createElement('div');
wrap.innerHTML = html;
var metaEl = wrap.querySelector('.homepagecache-footer, .homepagecache-meta');
var stamp = '';
if (metaEl) {
var m = metaEl.textContent.match(/Last updated:\s*(\S+)/i);
stamp = m ? m[1] : '';
metaEl.remove();
}
var items = title === 'News' ? splitNewsItems(wrap.innerHTML) : [];
var body;
if (title === 'News' && items.length) {
body = '<ul class="bp-vec-list">' + items.map(function (p) {
return '<li>' + p + '</li>';
}).join('') + '</ul>';
} else {
body = '<div class="bp-vec-body">' + wrap.innerHTML + '</div>';
}
el.innerHTML =
body +
'<div class="bp-vec-foot">' +
(moreHref ? '<a href="' + moreHref + '">' + moreLabel + '</a>' : '') +
(stamp ? '<span>Updated ' + stamp + '</span>' : '') +
'</div>';
}
async function loadHomepageCache() {
var res = await api.get({
action: 'parse',
page: HOMEPAGECACHE_PAGE,
prop: 'text',
disablelimitreport: 1,
disableeditsection: 1,
formatversion: 2
});
var tmp = document.createElement('div');
tmp.innerHTML = (res.parse && res.parse.text) || '';
return {
news: localizeWikiLinks(tmp.querySelector('.homepagecache-india-news') && tmp.querySelector('.homepagecache-india-news').innerHTML),
dyk: localizeWikiLinks(tmp.querySelector('.homepagecache-india-dyk') && tmp.querySelector('.homepagecache-india-dyk').innerHTML)
};
}
var monthNames = [
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
];
async function getYearPage(y) {
try {
var res = await api.get({
action: 'parse',
page: y + ' in India',
prop: 'wikitext',
formatversion: 2
});
return (res.parse && res.parse.wikitext) || '';
} catch (e) {
return '';
}
}
function extractChapter(wikitext, name) {
var re = new RegExp(
'^==\\s*' + name + '\\s*==\\s*$([\\s\\S]*?)(?=^==\\s*[^=\\n]+\\s*==\\s*$)',
'im'
);
var match = wikitext.match(re);
return match ? match[1] : '';
}
function extractMonthSection(source, monthName, y) {
var escaped = monthName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
var headingRegex = new RegExp(
'^={2,4}\\s*' + escaped + '(?:\\s+' + y + ')?\\s*={2,4}\\s*$',
'im'
);
var headingMatch = headingRegex.exec(source);
if (!headingMatch) {
return '';
}
var remaining = source.substring(headingMatch.index + headingMatch[0].length);
var nextHeading = remaining.search(/^={2,4}\s*[^=\n]+\s*={2,4}\s*$/m);
return nextHeading >= 0 ? remaining.substring(0, nextHeading) : remaining;
}
function parseMonthEvents(wikitext, monthIndex, y) {
var section = extractMonthSection(extractChapter(wikitext, 'Events') || wikitext, monthNames[monthIndex], y);
if (!section) {
return [];
}
var events = [];
var currentDay = null;
section.split(/\r?\n/).forEach(function (line) {
var dateOnly = line.match(/^\s*\*\s*(\d{1,2})\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s*(?:–|-|—)\s*$/i);
var dateWithText = line.match(/^\s*\*\s*(\d{1,2})\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s*(?:–|-|—)\s+(.+)$/i);
if (dateOnly) {
currentDay = parseInt(dateOnly[1], 10);
return;
}
if (dateWithText) {
currentDay = parseInt(dateWithText[1], 10);
events.push({ day: currentDay, month: monthIndex, year: y, title: dateWithText[3] });
return;
}
if (currentDay && /^\s*\*{2,}\s*\S/.test(line)) {
events.push({
day: currentDay,
month: monthIndex,
year: y,
title: line.replace(/^\s*\*+\s*/, '')
});
}
});
return events;
}
function firstLink(text) {
var raw = String(text || '');
var match = raw.match(/\[\[([^\[\]]+)\]\]/);
if (!match) {
return { title: '', text: '', after: raw };
}
var parts = match[1].split('|');
return {
title: (parts[0] || '').trim(),
text: (parts[1] || parts[0] || '').trim()
};
}
function cleanPlain(text) {
return String(text || '')
.replace(/\[\[([^|\]]+)\|([^\]]+)\]\]/g, '$2')
.replace(/\[\[([^\]]+)\]\]/g, '$1')
.replace(/\{\{[^{}]*\}\}/g, '')
.replace(/<ref[\s\S]*?<\/ref>/gi, '')
.replace(/<ref[^>]*\/?>/gi, '')
.replace(/'''|''/g, '')
.replace(/<[^>]+>/g, '')
.replace(/\s+/g, ' ')
.replace(/\.+$/, '')
.trim();
}
function parseDeaths(wikitext, year) {
var section = extractChapter(wikitext, 'Deaths');
if (!section) {
return [];
}
var deaths = [];
var current = null;
section.split(/\r?\n/).forEach(function (line) {
var dateOnly = line.match(/^\s*\*\s*(\d{1,2})\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s*(?:–|-|—)\s*$/i);
var dateWithText = line.match(/^\s*\*\s*(\d{1,2})\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s*(?:–|-|—)\s+(.+)$/i);
if (dateOnly) {
current = { day: parseInt(dateOnly[1], 10), month: monthNames.findIndex(function (m) { return m.toLowerCase() === dateOnly[2].toLowerCase(); }) };
return;
}
if (dateWithText) {
current = { day: parseInt(dateWithText[1], 10), month: monthNames.findIndex(function (m) { return m.toLowerCase() === dateWithText[2].toLowerCase(); }) };
deaths.push({ day: current.day, month: current.month, year: year, raw: dateWithText[3] });
return;
}
if (current && /^\s*\*{2,}\s*\[\[/.test(line)) {
deaths.push({ day: current.day, month: current.month, year: year, raw: line.replace(/^\s*\*+\s*/, '') });
}
});
return deaths.map(function (item) {
var link = firstLink(item.raw);
var plain = cleanPlain(item.raw);
var bits = plain.split(',');
return {
day: item.day,
month: item.month,
year: item.year,
name: link.text || (bits[0] || '').trim(),
detail: bits.slice(1).join(',').trim(),
url: link.title ? mw.util.getUrl(link.title) : mw.util.getUrl(year + ' in India') + '#Deaths'
};
}).filter(function (item) { return item.name; });
}
function injectStyles() {
if ($('bp-vector-home-style')) {
return;
}
var st = document.createElement('style');
st.id = 'bp-vector-home-style';
st.textContent = [
'.bp-vec-list, .bp-vec-events { margin: .4em 0 0; padding-left: 1.2em; }',
'.bp-vec-list li, .bp-vec-events li { margin: .45em 0; line-height: 1.45; }',
'.bp-vec-body { line-height: 1.45; }',
'.bp-vec-body li { margin: .35em 0; }',
'.bp-vec-foot { display: flex; justify-content: space-between; gap: 12px; margin-top: .8em; font-size: 90%; }',
'.bp-vec-foot span { color: #54595d; }',
'.bp-vec-empty, .bp-vec-loading { color: #54595d; font-size: 90%; }',
'.bp-vec-death { display: block; margin: .35em 0; text-decoration: none; }',
'.bp-vec-death small { display: block; color: #54595d; }',
'.bp-vec-date { font-weight: 700; margin-right: .35em; }'
].join('\n');
document.head.appendChild(st);
}
async function fillNewsDyk() {
var newsEl = $('bp-vector-news');
var dykEl = $('bp-vector-dyk');
if (!newsEl && !dykEl) {
return;
}
try {
var slots = await loadHomepageCache();
renderSlot(newsEl, 'News', slots.news, mw.util.getUrl('Portal:India/News'), 'All news');
renderSlot(dykEl, 'Did you know', slots.dyk, mw.util.getUrl('Portal:India/DYK'), 'All did you know');
} catch (e) {
console.error('Vector homepage cache failed', e);
if (newsEl) {
newsEl.innerHTML = '<p class="bp-vec-empty">News could not be loaded.</p>';
}
if (dykEl) {
dykEl.innerHTML = '<p class="bp-vec-empty">Did you know could not be loaded.</p>';
}
}
}
async function fillEvents() {
var el = $('bp-vector-events');
if (!el) {
return;
}
var today = istNow();
var year = today.getFullYear();
var month = today.getMonth();
var todayDay = today.getDate();
try {
var wikitext = await getYearPage(year);
var events = parseMonthEvents(wikitext, month, year).filter(function (ev) {
return ev.day <= todayDay;
});
events.sort(function (a, b) {
return (b.year * 10000 + (b.month + 1) * 100 + b.day) - (a.year * 10000 + (a.month + 1) * 100 + a.day);
});
if (events.length < 5) {
var prevMonth = month - 1;
var prevYear = year;
var prevText = wikitext;
if (prevMonth < 0) {
prevMonth = 11;
prevYear -= 1;
prevText = await getYearPage(prevYear);
}
events = events.concat(parseMonthEvents(prevText, prevMonth, prevYear));
events.sort(function (a, b) {
return (b.year * 10000 + (b.month + 1) * 100 + b.day) - (a.year * 10000 + (a.month + 1) * 100 + a.day);
});
}
events = events.slice(0, 5);
if (!events.length) {
el.innerHTML = '<p class="bp-vec-empty">No recent events listed on ' + year + ' in India.</p>';
return;
}
el.innerHTML =
'<ul class="bp-vec-events">' +
events.map(function (ev) {
return '<li><span class="bp-vec-date">' + String(ev.day).padStart(2, '0') + ' ' + monthNames[ev.month] + '</span> ' + wikiToHtml(ev.title) + '</li>';
}).join('') +
'</ul>' +
'<div class="bp-vec-foot"><a href="' + mw.util.getUrl(year + ' in India') + '#Events">All events</a><span>From ' + year + ' in India</span></div>';
} catch (e) {
console.error(e);
el.innerHTML = '<p class="bp-vec-empty">Events could not be loaded.</p>';
}
}
async function fillDeaths() {
var el = $('bp-vector-deaths');
if (!el) {
return;
}
var today = istNow();
var year = today.getFullYear();
try {
var wikitext = await getYearPage(year);
var todayStamp = year * 10000 + (today.getMonth() + 1) * 100 + today.getDate();
var recent = parseDeaths(wikitext, year).filter(function (item) {
return item.year * 10000 + (item.month + 1) * 100 + item.day <= todayStamp;
}).sort(function (a, b) {
return (b.year * 10000 + (b.month + 1) * 100 + b.day) - (a.year * 10000 + (a.month + 1) * 100 + a.day);
}).slice(0, 5);
if (!recent.length) {
el.innerHTML = '<p class="bp-vec-empty">No recent deaths listed.</p>';
return;
}
el.innerHTML = recent.map(function (item) {
var mon = (monthNames[item.month] || '').substring(0, 3);
return '<a class="bp-vec-death" href="' + item.url + '"><span class="bp-vec-date">' + String(item.day).padStart(2, '0') + ' ' + mon + '</span> <b>' + item.name + '</b>' +
(item.detail ? '<small>' + item.detail + '</small>' : '') + '</a>';
}).join('') +
'<div class="bp-vec-foot"><a href="' + mw.util.getUrl(year + ' in India') + '#Deaths">All deaths</a></div>';
} catch (e) {
console.error(e);
el.innerHTML = '<p class="bp-vec-empty">Deaths could not be loaded.</p>';
}
}
function boot() {
injectStyles();
fillNewsDyk();
fillEvents();
fillDeaths();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot);
} else {
boot();
}
}());