MediaWiki

BibTest.js: Difference between revisions

From Illustrations in German Translations of Mark Twain's Works

No edit summary
No edit summary
 
(6 intermediate revisions by the same user not shown)
Line 2: Line 2:
  * Bibliography Tag Filter, Sorting and Search
  * Bibliography Tag Filter, Sorting and Search
  */
  */
function updateCounter() {
  const entries = document.querySelectorAll('.bib-entry');
  const visible = Array.from(entries).filter(entry => entry.style.display !== 'none').length;


  const counter = document.getElementById('bibCounter');
  if (counter) {
    counter.textContent = `${visible} of ${entries.length} sources shown`;
  }
}
(function() {
(function() {
   'use strict';
   'use strict';
Line 37: Line 45:


   // Sonderfarbe für Twain-Werke
   // Sonderfarbe für Twain-Werke
  const orangeTags = [
const orangeTags = [
    'a connecticut yankee in king arthur\'s court',
  'a connecticut yankee in king arthur\'s court',
    'adventures of huckleberry finn',
  'adventures of huckleberry finn',
    'pudd\'nhead wilson',
  'pudd\'nhead wilson',
    'roughing it',
  'roughing it',
    'the adventures of tom sawyer',
  'the adventures of tom sawyer',
    'the innocents abroad'
  'the innocents abroad',
   ];
   'a tramp abroad'
];
 
if (orangeTags.includes(originalName.toLowerCase())) {
  span.classList.add('twain-work');
}


  if (orangeTags.includes(originalName.toLowerCase())) {
// Sonderfarbe für Illustratoren
    span.classList.add('twain-work');
  }
  // Sonderfarbe für Illustratoren
const illustratorTags = [
const illustratorTags = [
   'kemble, edward w.',
   'kemble, edward w.',
   'senior, frank m.',
   'senior, frank m.',
   'warren, calvin h.',
   'warren, calvin h.',
   'williams, truman w.'
   'williams, true w.',
  'brown, walter f.',
  'beard, daniel carter'
];
];
if (illustratorTags.includes(originalName.toLowerCase())) {
  span.classList.add('illustrator-tag');
}


   span.onclick = () => toggleTag(originalName, span, normalized);
   span.onclick = () => toggleTag(originalName, span, normalized);
Line 61: Line 77:
});
});
     }
     }
    // Info-Legende für Tag-Farben
    if (!document.getElementById('tagLegend')) {
      const legend = document.createElement('span');
      legend.id = 'tagLegend';
      legend.innerHTML = `
        <span class="info-icon">i</span>
        <div class="legend-box">
          <div><span class="legend-color twain"></span> Twain's Works</div>
          <div><span class="legend-color illustrator"></span> Illustrators</div>
          <div><span class="legend-color general"></span> General Tags</div>
        </div>
      `;


      tagBar.appendChild(legend);
    }
     // Search Input Listener
     // Search Input Listener
     if (searchInput && !searchInput.dataset.listenerSet) {
     if (searchInput && !searchInput.dataset.listenerSet) {
Line 75: Line 106:




if (illustratorTags.includes(originalName.toLowerCase())) {
 
  span.classList.add('illustrator-tag');
}


removeEmptyAbstractButtons();
removeEmptyAbstractButtons();
Line 257: Line 286:
       entry.style.display = (matchesTags && matchesSearchTerm) ? 'block' : 'none';
       entry.style.display = (matchesTags && matchesSearchTerm) ? 'block' : 'none';
     });
     });
    updateCounter();
   }
   }


Line 268: Line 298:
   document.addEventListener('DOMContentLoaded', init);
   document.addEventListener('DOMContentLoaded', init);
})();
})();
updateCounter();

Latest revision as of 00:12, 17 July 2026

/**
 * Bibliography Tag Filter, Sorting and Search
 */
function updateCounter() {
  const entries = document.querySelectorAll('.bib-entry');
  const visible = Array.from(entries).filter(entry => entry.style.display !== 'none').length;

  const counter = document.getElementById('bibCounter');
  if (counter) {
    counter.textContent = `${visible} of ${entries.length} sources shown`;
  }
}
(function() {
  'use strict';

  let ACTIVE_TAGS = new Set();
  let SEARCH_TERM = '';

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

    

    // Sammle alle Original-Tagnamen aus den Einträgen
    const allTagsMap = new Map();
    document.querySelectorAll('.bib-entry .tag').forEach(tagEl => {
      const originalName = tagEl.textContent.trim();
      const normalized = normalizeTag(originalName);
      allTagsMap.set(normalized, originalName);
    });

    // Lösche alte Tags aus tagBar (aber nur einmal!)
    if (tagBar.children.length === 0) {
      Array.from(allTagsMap.entries())
        .sort((a, b) => a[1].localeCompare(b[1]))
        .forEach(([normalized, originalName]) => {
  const span = document.createElement('span');
  span.className = 'tag inactive';
  span.textContent = originalName;
  span.dataset.normalized = normalized;

  // Sonderfarbe für Twain-Werke
const orangeTags = [
  'a connecticut yankee in king arthur\'s court',
  'adventures of huckleberry finn',
  'pudd\'nhead wilson',
  'roughing it',
  'the adventures of tom sawyer',
  'the innocents abroad',
  'a tramp abroad'
];

if (orangeTags.includes(originalName.toLowerCase())) {
  span.classList.add('twain-work');
}

// Sonderfarbe für Illustratoren
const illustratorTags = [
  'kemble, edward w.',
  'senior, frank m.',
  'warren, calvin h.',
  'williams, true w.',
  'brown, walter f.',
  'beard, daniel carter'
];

if (illustratorTags.includes(originalName.toLowerCase())) {
  span.classList.add('illustrator-tag');
}

  span.onclick = () => toggleTag(originalName, span, normalized);
  tagBar.appendChild(span);
});
    }
    // Info-Legende für Tag-Farben
    if (!document.getElementById('tagLegend')) {
      const legend = document.createElement('span');
      legend.id = 'tagLegend';

      legend.innerHTML = `
        <span class="info-icon">i</span>
        <div class="legend-box">
          <div><span class="legend-color twain"></span> Twain's Works</div>
          <div><span class="legend-color illustrator"></span> Illustrators</div>
          <div><span class="legend-color general"></span> General Tags</div>
        </div>
      `;

      tagBar.appendChild(legend);
    }
    // Search Input Listener
    if (searchInput && !searchInput.dataset.listenerSet) {
      searchInput.addEventListener('input', (e) => {
        SEARCH_TERM = e.target.value.toLowerCase();
        filterEntries();
      });
      searchInput.dataset.listenerSet = 'true';
    }

    sortEntries();





removeEmptyAbstractButtons();
removeEmptyNotesButtons();

collapseAbstractsInitially();
collapseNotesInitially();

setupClickHandlers();
  }

 function removeEmptyAbstractButtons() {
  document.querySelectorAll('.bib-entry').forEach(entry => {

    const abstractDiv = entry.querySelector('.abstract');
    const button = entry.querySelector('.expand-btn');

    if (!abstractDiv || !button) return;

    const text = abstractDiv.textContent.trim();

    // Nur prüfen ob leer bzw. Platzhaltertext
    if (
      text === '' ||
      text === 'No abstract available.'
      
    ) {
      button.remove();
      abstractDiv.remove();
    }
  });
}
function collapseAbstractsInitially() {
  document.querySelectorAll('.abstract').forEach(el => {
    el.classList.add('hidden');
    el.style.display = ''; // entfernt evtl. inline overrides
  });
}

function removeEmptyNotesButtons() {
  document.querySelectorAll('.bib-entry').forEach(entry => {

    const notesDiv = entry.querySelector('.notes');
    const button = entry.querySelector('.expand-btn-notes');

    if (!notesDiv || !button) return;

    const text = notesDiv.textContent.trim();

    if (text === '') {
      button.remove();
      notesDiv.remove();
    }
  });
}
function collapseNotesInitially() {
  document.querySelectorAll('.notes').forEach(notesDiv => {
    notesDiv.classList.add('hidden');
  });
}
  function setupClickHandlers() {
    document.removeEventListener('click', handleClicks);
    document.addEventListener('click', handleClicks);
  }

  function handleClicks(e) {

  // =========================
  // ABSTRACT TOGGLE
  // =========================
  if (e.target.classList.contains('expand-btn') &&
      !e.target.classList.contains('expand-btn-notes')) {

    const entry = e.target.closest('.bib-entry');
    const abstractDiv = entry?.querySelector('.abstract');

    if (!abstractDiv) return;

    const isHidden = abstractDiv.classList.toggle('hidden');

    e.target.textContent = isHidden
      ? 'Show Abstract'
      : 'Hide Abstract';
  }

  // =========================
  // NOTES TOGGLE
  // =========================
  if (e.target.classList.contains('expand-btn-notes')) {

    const entry = e.target.closest('.bib-entry');
    const notesDiv = entry?.querySelector('.notes');

    if (!notesDiv) return;

    const isHidden = notesDiv.classList.toggle('hidden');

    e.target.textContent = isHidden
      ? 'Show Notes'
      : 'Hide Notes';
  }
}

  function toggleTag(tagName, element, normalized) {
    if (ACTIVE_TAGS.has(normalized)) {
      ACTIVE_TAGS.delete(normalized);
      element.classList.remove('active');
      element.classList.add('inactive');
    } else {
      ACTIVE_TAGS.add(normalized);
      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);
    });

    entries.forEach(entry => container.appendChild(entry));
  }

  function normalizeTag(tag) {
    return tag.toLowerCase().replace(/\s+/g, '_').replace(/,/g, '').replace(/\./g, '').replace(/'/g, '').replace(/"/g, '');
  }

  function matchesSearch(entry) {
    if (!SEARCH_TERM) return true;

    const searchText = SEARCH_TERM;
    
    const title = entry.querySelector('h3')?.textContent || '';
    if (title.toLowerCase().includes(searchText)) return true;

    const tagElements = entry.querySelectorAll('.tag');
    for (let tag of tagElements) {
      if (tag.textContent.toLowerCase().includes(searchText)) return true;
    }

    const abstractDiv = entry.querySelector('.abstract');
    if (abstractDiv) {
      const abstractText = abstractDiv.textContent || '';
      if (abstractText.toLowerCase().includes(searchText)) return true;
    }

    const notesDiv = entry.querySelector('.notes');
    if (notesDiv) {
      const notesText = notesDiv.textContent || '';
      if (notesText.toLowerCase().includes(searchText)) return true;
    }

    return false;
  }

  function filterEntries() {
    const entries = document.querySelectorAll('.bib-entry');
    
    entries.forEach(entry => {
      const entryTags = (entry.getAttribute('data-tags') || '').split(' ').filter(t => t);
      
      let matchesTags = true;
      if (ACTIVE_TAGS.size > 0) {
        matchesTags = Array.from(ACTIVE_TAGS).every(activeTag => {
          return entryTags.includes(activeTag);
        });
      }

      const matchesSearchTerm = matchesSearch(entry);

      entry.style.display = (matchesTags && matchesSearchTerm) ? 'block' : 'none';
    });
    updateCounter();
  }

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

  document.addEventListener('DOMContentLoaded', init);
})();
updateCounter();