Jump to content

MediaWiki:Gadget-OralHistoryRecords-Updated.js

Revision as of 17:42, 22 February 2026 by Hthach (talk | contribs)

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.
/* ===== OralHistoryRecords-Updated.js ===== */
/* global mw */
(function () {
  'use strict';

  var COL = {
    personKey: 'Person Key',
    first: 'First Name',
    last: 'Last Name',
    birth: 'Birth Year',
    death: 'Death Year',
    dateFrom: 'Date From',
    dateTo: 'Date To',
    bio: 'Short Bio',
    wiki: 'Wiki Link',
    audio: 'Audio Link',
    video: 'Video Link',
    transcripts: 'Transcript Link'
  };

  var PEOPLE = [];
  var FILTER = { q: '' };

  function $(id) { return document.getElementById(id); }

  function onReady(fn) {
    if (document.readyState !== 'loading') fn();
    else document.addEventListener('DOMContentLoaded', fn);
  }

  function esc(s) {
    return (s || '').replace(/[&<>"']/g, function (c) {
      return ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]);
    });
  }

  function norm(s) {
    return (s || '').toString().toLowerCase();
  }

  function debounce(fn, ms) {
    var t;
    return function () {
      var a = arguments, self = this;
      clearTimeout(t);
      t = setTimeout(function () { fn.apply(self, a); }, ms);
    };
  }

  function extractUrls(value) {
    if (!value) return [];
    var re = /https?:\/\/[^\s"'<>()]+/g;
    return (value.match(re) || []);
  }

  function buildToolbar(root) {
    var toolbar = document.createElement('div');
    toolbar.className = 'ohr-toolbar';

    var search = document.createElement('input');
    search.id = 'ohr-search';
    search.type = 'search';
    search.placeholder = 'Search names, bios…';

    var count = document.createElement('div');
    count.id = 'ohr-count';
    count.className = 'ohr-count';

    toolbar.appendChild(search);
    toolbar.appendChild(count);
    root.insertBefore(toolbar, root.firstChild);
  }

  function makeAccordionPerson(person, idx) {
    var div = document.createElement('div');
    div.className = 'ohr-item';

    var panelId = 'ohr-panel-' + idx;
    var btnId = 'ohr-btn-' + idx;

    div.innerHTML =
      '<div class="ohr-head">' +
        '<div class="ohr-titleblock">' +
          '<h3 class="ohr-name">' + esc(person.name) + '</h3>' +
        '</div>' +
        '<button class="ohr-acc-btn" id="' + btnId + '" type="button" aria-expanded="false" aria-controls="' + panelId + '">Details</button>' +
      '</div>' +
      '<div class="ohr-acc-panel ohr-hidden" id="' + panelId + '">' +
        person.content +
      '</div>';

    var btn = div.querySelector('#' + btnId);
    var panel = div.querySelector('#' + panelId);

    if (btn && panel) {
      btn.addEventListener('click', function () {
        var isOpen = !panel.classList.contains('ohr-hidden');

        if (isOpen) {
          panel.classList.add('ohr-hidden');
          div.classList.remove('is-open');
          btn.setAttribute('aria-expanded', 'false');
          btn.textContent = 'Details';
        } else {
          panel.classList.remove('ohr-hidden');
          div.classList.add('is-open');
          btn.setAttribute('aria-expanded', 'true');
          btn.textContent = 'Hide';
        }
      });
    }

    return div;
  }

  onReady(function () {
    if ($('ohr-directory')) {
      buildToolbar($('ohr-directory'));
    }
  });

})();