BibTest.js: Difference between revisions
From Illustrations in German Translations of Mark Twain's Works
No edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
( | (function () { | ||
const DATA_URL = " | const DATA_URL = "/index.php?title=BibliographyData&action=raw&ctype=application/json"; | ||
let DATA = []; | let DATA = []; | ||
let ACTIVE_TAGS = new Set(); | let ACTIVE_TAGS = new Set(); | ||
// - | // MediaWiki-safe init | ||
if (document.readyState === "loading") { | |||
document.addEventListener("DOMContentLoaded", init); | document.addEventListener("DOMContentLoaded", init); | ||
} else { | |||
init(); | |||
} | |||
async function init() { | async function init() { | ||
await loadData(); | try { | ||
await loadData(); | |||
renderTags(); | |||
renderList(); | |||
} catch (e) { | |||
console.error("Bibliography load error:", e); | |||
} | |||
} | } | ||
| Line 22: | Line 29: | ||
DATA = await res.json(); | DATA = await res.json(); | ||
// | // alphabetisch sortieren | ||
DATA.sort((a, b) => | DATA.sort((a, b) => | ||
(a.title || "").localeCompare(b.title || "") | (a.title || "").localeCompare(b.title || "") | ||
| Line 28: | Line 35: | ||
} | } | ||
// -------------------- | // -------------------- TAGS -------------------- | ||
function renderTags() { | function renderTags() { | ||
const tagBar = document.getElementById("tagBar"); | const tagBar = document.getElementById("tagBar"); | ||
if (!tagBar) return; | |||
tagBar.innerHTML = ""; | tagBar.innerHTML = ""; | ||
const | const tags = new Set(); | ||
DATA.forEach(item => { | DATA.forEach(item => { | ||
(item.tags || []).forEach(t => | (item.tags || []).forEach(t => tags.add(t)); | ||
}); | }); | ||
[... | [...tags].sort().forEach(tag => { | ||
const el = document.createElement("span"); | const el = document.createElement("span"); | ||
el.className = "tag inactive"; | el.className = "tag inactive"; | ||
el.textContent = tag; | el.textContent = tag; | ||
el.onclick = () => toggleTag(tag | el.onclick = () => toggleTag(tag); | ||
tagBar.appendChild(el); | tagBar.appendChild(el); | ||
| Line 52: | Line 60: | ||
} | } | ||
function toggleTag(tag | function toggleTag(tag) { | ||
if (ACTIVE_TAGS.has(tag)) { | if (ACTIVE_TAGS.has(tag)) { | ||
ACTIVE_TAGS.delete(tag); | ACTIVE_TAGS.delete(tag); | ||
} else { | } else { | ||
ACTIVE_TAGS.add(tag); | ACTIVE_TAGS.add(tag); | ||
} | } | ||
updateTagStyles(); | |||
renderList(); | renderList(); | ||
} | } | ||
// -------------------- LIST | function updateTagStyles() { | ||
document.querySelectorAll("#tagBar .tag").forEach(el => { | |||
const t = el.textContent; | |||
if (ACTIVE_TAGS.has(t)) { | |||
el.classList.add("active"); | |||
el.classList.remove("inactive"); | |||
} else { | |||
el.classList.remove("active"); | |||
el.classList.add("inactive"); | |||
} | |||
}); | |||
} | |||
// -------------------- LIST -------------------- | |||
function renderList() { | function renderList() { | ||
const container = document.getElementById("listView"); | const container = document.getElementById("listView"); | ||
if (!container) return; | |||
container.innerHTML = ""; | container.innerHTML = ""; | ||
| Line 76: | Line 97: | ||
if (ACTIVE_TAGS.size > 0) { | if (ACTIVE_TAGS.size > 0) { | ||
filtered = DATA.filter(item => | filtered = DATA.filter(item => | ||
item.tags | (item.tags || []).some(t => ACTIVE_TAGS.has(t)) | ||
); | ); | ||
} | } | ||
| Line 84: | Line 105: | ||
div.className = "bib-entry"; | div.className = "bib-entry"; | ||
div.innerHTML = | div.innerHTML = renderEntry(item); | ||
container.appendChild(div); | container.appendChild(div); | ||
| Line 90: | Line 111: | ||
} | } | ||
// -------------------- ENTRY | // -------------------- ENTRY -------------------- | ||
function | function renderEntry(item) { | ||
const authors = (item.authors || []) | const authors = (item.authors || []) | ||
.map(a => | .map(a => typeof a === "string" | ||
? a | |||
: (a.family || "Unknown")) | |||
.join(", "); | .join(", "); | ||
const tags = (item.tags || []).map(t => | const tags = (item.tags || []).map(t => | ||
`<span class="tag ${ACTIVE_TAGS.has(t) ? 'active' : 'inactive'} | `<span class="tag ${ACTIVE_TAGS.has(t) ? 'active' : 'inactive'}"> | ||
${t} | ${t} | ||
</span>` | </span>` | ||
| Line 110: | Line 128: | ||
return ` | return ` | ||
<h3>${authors || "Unknown"}. <i>${item.title || "Untitled"}</i>. ${item.year || ""}</h3> | <h3> | ||
${authors || "Unknown"}. | |||
<i>${item.title || "Untitled"}</i>. | |||
${item.year || ""} | |||
</h3> | |||
<div class="bib-tags">${tags}</div> | <div class="bib-tags">${tags}</div> | ||
<p | ${item.container ? `<p><em>${item.container}</em></p>` : ""} | ||
${item.url ? `<a href="${item.url}" target="_blank">Source</a>` : ""} | ${item.url ? `<a href="${item.url}" target="_blank">Source</a>` : ""} | ||
`; | `; | ||
} | } | ||
})(); | })(); | ||
Revision as of 23:46, 11 May 2026
(function () {
const DATA_URL = "/index.php?title=BibliographyData&action=raw&ctype=application/json";
let DATA = [];
let ACTIVE_TAGS = new Set();
// MediaWiki-safe init
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
async function init() {
try {
await loadData();
renderTags();
renderList();
} catch (e) {
console.error("Bibliography load error:", e);
}
}
// -------------------- LOAD DATA --------------------
async function loadData() {
const res = await fetch(DATA_URL);
DATA = await res.json();
// alphabetisch sortieren
DATA.sort((a, b) =>
(a.title || "").localeCompare(b.title || "")
);
}
// -------------------- TAGS --------------------
function renderTags() {
const tagBar = document.getElementById("tagBar");
if (!tagBar) return;
tagBar.innerHTML = "";
const tags = new Set();
DATA.forEach(item => {
(item.tags || []).forEach(t => tags.add(t));
});
[...tags].sort().forEach(tag => {
const el = document.createElement("span");
el.className = "tag inactive";
el.textContent = tag;
el.onclick = () => toggleTag(tag);
tagBar.appendChild(el);
});
}
function toggleTag(tag) {
if (ACTIVE_TAGS.has(tag)) {
ACTIVE_TAGS.delete(tag);
} else {
ACTIVE_TAGS.add(tag);
}
updateTagStyles();
renderList();
}
function updateTagStyles() {
document.querySelectorAll("#tagBar .tag").forEach(el => {
const t = el.textContent;
if (ACTIVE_TAGS.has(t)) {
el.classList.add("active");
el.classList.remove("inactive");
} else {
el.classList.remove("active");
el.classList.add("inactive");
}
});
}
// -------------------- LIST --------------------
function renderList() {
const container = document.getElementById("listView");
if (!container) return;
container.innerHTML = "";
let filtered = DATA;
if (ACTIVE_TAGS.size > 0) {
filtered = DATA.filter(item =>
(item.tags || []).some(t => ACTIVE_TAGS.has(t))
);
}
filtered.forEach(item => {
const div = document.createElement("div");
div.className = "bib-entry";
div.innerHTML = renderEntry(item);
container.appendChild(div);
});
}
// -------------------- ENTRY --------------------
function renderEntry(item) {
const authors = (item.authors || [])
.map(a => typeof a === "string"
? a
: (a.family || "Unknown"))
.join(", ");
const tags = (item.tags || []).map(t =>
`<span class="tag ${ACTIVE_TAGS.has(t) ? 'active' : 'inactive'}">
${t}
</span>`
).join(" ");
return `
<h3>
${authors || "Unknown"}.
<i>${item.title || "Untitled"}</i>.
${item.year || ""}
</h3>
<div class="bib-tags">${tags}</div>
${item.container ? `<p><em>${item.container}</em></p>` : ""}
${item.url ? `<a href="${item.url}" target="_blank">Source</a>` : ""}
`;
}
})();