MediaWiki:Common.js: Difference between revisions
Appearance
Created page with "(function () { function injectSojiFooter() { var footer = document.getElementById("footer"); if (!footer || document.getElementById("soji-site-footer")) { return; } var html = [ '<section id="soji-site-footer" class="soji-site-footer">', ' <div class="soji-footer-shell">', ' <div class="soji-footer-grid">', ' <section class="soji-footer-col">', ' <..." |
No edit summary |
||
| Line 1: | Line 1: | ||
(function () { | (function () { | ||
function | function esc(text) { | ||
var footer = | return String(text || "").replace(/[&<>"]/g, function (m) { | ||
return { "&": "&", "<": "<", ">": ">", '"': """ }[m]; | |||
return; | }); | ||
} | } | ||
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">', | '<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(""); | ].join(""); | ||
} | |||
footer.insertAdjacentHTML("beforebegin", | 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"); | 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") { | if (document.readyState === "loading") { | ||
document.addEventListener("DOMContentLoaded", | document.addEventListener("DOMContentLoaded", init); | ||
} else { | } else { | ||
init(); | |||
} | } | ||
})(); | })(); | ||
Revision as of 07:28, 11 May 2026
(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();
}
})();