MediaWiki

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 () {
/**
* Bibliography Tag Filter and Sorting
* Lädt automatisch wenn die Seite "Bibliography" aufgerufen wird
*/


const DATA_URL = "/index.php?title=BibliographyData&action=raw&ctype=application/json";
(function() {
  'use strict';


let DATA = [];
  let ACTIVE_TAGS = new Set();
let ACTIVE_TAGS = new Set();


// MediaWiki-safe init
  function init() {
if (document.readyState === "loading") {
    const tagBar = document.getElementById('tagBar');
     document.addEventListener("DOMContentLoaded", init);
     const bibliography = document.getElementById('listView');
} else {
   
     init();
     if (!tagBar || !bibliography) return;
}


async function init() {
     // Sammle alle verfügbaren Tags
     try {
     const allTags = new Set();
        await loadData();
     document.querySelectorAll('.bib-entry').forEach(entry => {
        renderTags();
      const tags = entry.getAttribute('data-tags');
        renderList();
      if (tags) {
    } catch (e) {
        tags.split(' ').forEach(tag => allTags.add(tag));
        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 => {
     // Sortiere und zeige Tags
        (item.tags || []).forEach(t => tags.add(t));
    const sortedTags = Array.from(allTags).sort();
    tagBar.innerHTML = '';
    sortedTags.forEach(tag => {
      const span = document.createElement('span');
      span.className = 'tag inactive';
      span.textContent = tag;
      span.style.cursor = 'pointer';
      span.onclick = () => toggleTag(tag, span);
      tagBar.appendChild(span);
     });
     });


     [...tags].sort().forEach(tag => {
     // Sortiere Einträge alphabetisch
        const el = document.createElement("span");
    sortEntries();
        el.className = "tag inactive";
  }
        el.textContent = tag;
 
        el.onclick = () => toggleTag(tag);
 
        tagBar.appendChild(el);
    });
}


function toggleTag(tag) {
  function toggleTag(tag, element) {
     if (ACTIVE_TAGS.has(tag)) {
     if (ACTIVE_TAGS.has(tag)) {
        ACTIVE_TAGS.delete(tag);
      ACTIVE_TAGS.delete(tag);
      element.classList.remove('active');
      element.classList.add('inactive');
     } else {
     } else {
        ACTIVE_TAGS.add(tag);
      ACTIVE_TAGS.add(tag);
      element.classList.add('active');
      element.classList.remove('inactive');
     }
     }
    filterEntries();
  }


    updateTagStyles();
  function sortEntries() {
     renderList();
     const container = document.getElementById('listView');
}
     if (!container) return;
 
function updateTagStyles() {
     document.querySelectorAll("#tagBar .tag").forEach(el => {
        const t = el.textContent;


        if (ACTIVE_TAGS.has(t)) {
    const entries = Array.from(container.querySelectorAll('.bib-entry'));
            el.classList.add("active");
   
            el.classList.remove("inactive");
    entries.sort((a, b) => {
        } else {
      const titleA = a.querySelector('h3')?.textContent || '';
            el.classList.remove("active");
      const titleB = b.querySelector('h3')?.textContent || '';
            el.classList.add("inactive");
      return titleA.localeCompare(titleB);
        }
     });
     });
}


// -------------------- LIST --------------------
    // Neu einfügen
    entries.forEach(entry => container.appendChild(entry));
  }


function renderList() {
  function filterEntries() {
     const container = document.getElementById("listView");
     const entries = document.querySelectorAll('.bib-entry');
     if (!container) return;
      
 
    entries.forEach(entry => {
    container.innerHTML = "";
      const entryTags = (entry.getAttribute('data-tags') || '').split(' ').filter(t => t);
 
     
     let filtered = DATA;
      if (ACTIVE_TAGS.size === 0) {
        entry.style.display = 'block';
      } else {
        // AND-Logik: Entry muss ALLE aktiven Tags haben
        const hasAllTags = Array.from(ACTIVE_TAGS).every(tag => entryTags.includes(tag));
        entry.style.display = hasAllTags ? 'block' : 'none';
      }
     });
  }


     if (ACTIVE_TAGS.size > 0) {
  // Abstract-Button Toggle
        filtered = DATA.filter(item =>
  document.addEventListener('click', function(e) {
            (item.tags || []).some(t => ACTIVE_TAGS.has(t))
     if (e.target.classList.contains('expand-btn')) {
        );
      const abstractDiv = e.target.nextElementSibling;
      if (abstractDiv && abstractDiv.classList.contains('abstract')) {
        abstractDiv.classList.toggle('hidden');
        e.target.textContent = abstractDiv.classList.contains('hidden')
          ? 'Show Abstract'
          : 'Hide Abstract';
      }
     }
     }
  });


    filtered.forEach(item => {
  // Starte wenn DOM bereit
        const div = document.createElement("div");
  if (document.readyState === 'loading') {
        div.className = "bib-entry";
    document.addEventListener('DOMContentLoaded', init);
 
  } else {
        div.innerHTML = renderEntry(item);
     init();
 
  }
        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>` : ""}
    `;
}
 
})();
})();

Revision as of 01:06, 12 May 2026

/**
 * Bibliography Tag Filter and Sorting
 * Lädt automatisch wenn die Seite "Bibliography" aufgerufen wird
 */

(function() {
  'use strict';

  let ACTIVE_TAGS = new Set();

  function init() {
    const tagBar = document.getElementById('tagBar');
    const bibliography = document.getElementById('listView');
    
    if (!tagBar || !bibliography) return;

    // Sammle alle verfügbaren Tags
    const allTags = new Set();
    document.querySelectorAll('.bib-entry').forEach(entry => {
      const tags = entry.getAttribute('data-tags');
      if (tags) {
        tags.split(' ').forEach(tag => allTags.add(tag));
      }
    });

    // Sortiere und zeige Tags
    const sortedTags = Array.from(allTags).sort();
    tagBar.innerHTML = '';
    sortedTags.forEach(tag => {
      const span = document.createElement('span');
      span.className = 'tag inactive';
      span.textContent = tag;
      span.style.cursor = 'pointer';
      span.onclick = () => toggleTag(tag, span);
      tagBar.appendChild(span);
    });

    // Sortiere Einträge alphabetisch
    sortEntries();
  }

  function toggleTag(tag, element) {
    if (ACTIVE_TAGS.has(tag)) {
      ACTIVE_TAGS.delete(tag);
      element.classList.remove('active');
      element.classList.add('inactive');
    } else {
      ACTIVE_TAGS.add(tag);
      element.classList.add('active');
      element.classList.remove('inactive');
    }
    filterEntries();
  }

  function sortEntries() {
    const container = document.getElementById('listView');
    if (!container) return;

    const entries = Array.from(container.querySelectorAll('.bib-entry'));
    
    entries.sort((a, b) => {
      const titleA = a.querySelector('h3')?.textContent || '';
      const titleB = b.querySelector('h3')?.textContent || '';
      return titleA.localeCompare(titleB);
    });

    // Neu einfügen
    entries.forEach(entry => container.appendChild(entry));
  }

  function filterEntries() {
    const entries = document.querySelectorAll('.bib-entry');
    
    entries.forEach(entry => {
      const entryTags = (entry.getAttribute('data-tags') || '').split(' ').filter(t => t);
      
      if (ACTIVE_TAGS.size === 0) {
        entry.style.display = 'block';
      } else {
        // AND-Logik: Entry muss ALLE aktiven Tags haben
        const hasAllTags = Array.from(ACTIVE_TAGS).every(tag => entryTags.includes(tag));
        entry.style.display = hasAllTags ? 'block' : 'none';
      }
    });
  }

  // Abstract-Button Toggle
  document.addEventListener('click', function(e) {
    if (e.target.classList.contains('expand-btn')) {
      const abstractDiv = e.target.nextElementSibling;
      if (abstractDiv && abstractDiv.classList.contains('abstract')) {
        abstractDiv.classList.toggle('hidden');
        e.target.textContent = abstractDiv.classList.contains('hidden')
          ? 'Show Abstract'
          : 'Hide Abstract';
      }
    }
  });

  // Starte wenn DOM bereit
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
})();