MediaWiki:Common.js
Appearance
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.
(function () {
function esc(text) {
return String(text || "").replace(/[&<>"]/g, function (m) {
return { "&": "&", "<": "<", ">": ">", '"': """ }[m];
});
}
function renderLink(item, extraClass) {
var cls = extraClass ? ' class="' + extraClass + '"' : "";
var href = item.href ? esc(item.href) : "#";
return '<a' + cls + ' href="' + href + '">' + esc(item.label) + "</a>";
}
function buildFooter(data) {
var columns = (data.columns || []).map(function (col) {
var items = (col.items || []).map(function (item) {
return "<li>" + renderLink(item, "soji-footer-link") + "</li>";
}).join("");
return [
'<section class="soji-footer-col">',
"<h2>" + esc(col.title) + "</h2>",
"<ul>" + items + "</ul>",
"</section>"
].join("");
}).join("");
var policies = (data.policies || []).map(function (item, i) {
return (i ? '<span class="soji-footer-sep">|</span>' : "") +
renderLink(item, "soji-footer-link");
}).join("");
var social = (data.social || []).map(function (item) {
var href = item.href ? esc(item.href) : "#";
return '<a class="soji-footer-social-item" href="' + href + '" aria-label="' + esc(item.label) + '">' +
esc(item.short || item.label.charAt(0)) + "</a>";
}).join("");
var subscribe = data.subscribe
? renderLink(data.subscribe, "soji-footer-subscribe")
: "";
return [
'<section id="soji-site-footer" class="soji-site-footer">',
'<div class="soji-footer-shell">',
'<div class="soji-footer-grid">' + columns + "</div>",
'<div class="soji-footer-bottom">',
'<div class="soji-footer-meta">',
'<div class="soji-footer-policy-row">' + policies + "</div>",
'<div class="soji-footer-copy">' + esc(data.copyright || "") + "</div>",
"</div>",
'<div class="soji-footer-actions">',
subscribe,
'<div class="soji-footer-social">',
'<span class="soji-footer-social-label">Connect</span>',
'<div class="soji-footer-social-list">' + social + "</div>",
"</div>",
"</div>",
"</div>",
"</div>",
"</section>"
].join("");
}
function injectFooter(data) {
var footer = document.getElementById("footer");
if (!footer || document.getElementById("soji-site-footer")) return;
footer.insertAdjacentHTML("beforebegin", buildFooter(data));
document.body.classList.add("has-soji-footer");
}
function init() {
fetch("/index.php?title=MediaWiki:FooterData.json&action=raw")
.then(function (r) { return r.text(); })
.then(function (text) { return JSON.parse(text); })
.then(injectFooter)
.catch(function (err) { console.error("Footer load failed:", err); });
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();