User:Valento/CollapsibleTables.js

From Final Fantasy XIV Online Wiki
Jump to navigation Jump to search

Note: After saving, 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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**** CollapsibleTables.js
 * (c) 2007–2014 by Patrick Westerhoff [poke]
 *
 * This class allows to make tables collapsible and adds a show/hide button to
 * affected tables. Tables which class attribute contains 'collapsible' or
 * 'expandable' are affected by this class and can be collapsed; the latter
 * automatically hides the content of all sections.
 * Header rows are used to divide the table into sections which can be collapsed
 * separately. By default the first row of the table is interpreted as a header
 * row, however this can be overwritten by adding 'collapsible' to the class
 * attribute of header rows. You can also hide a section individually by default
 * when in 'collapsible' mode by using 'expandable' as the row's class name
 * instead.
 */

(function (document, $) {
  if (!mw.config.get('wgIsArticle') && window.location.href.indexOf('action=submit') < 0 && mw.config.get('wgNamespaceNumber') == -1)
      return;

  var classCollapsible = 'collapsible';
  var classExpandable = 'expandable';
  var linkTextShow = '[show]';
  var linkTextHide = '[hide]';

  var reClassName = new RegExp('(?:\\s|^)(' + classCollapsible + '|' + classExpandable + ')(?:\\s|$)');
  var sections = [];

  // link element
  var linkElement = document.createElement('a');
  linkElement.style.fontSize = '85%';
  linkElement.style.fontWeight = 'normal';
  linkElement.style.width = '3em';
  linkElement.style.cssFloat = 'right';
  linkElement.style.styleFloat = 'right';
  linkElement.style.textAlign = 'center';
  linkElement.style.marginLeft = '1em';
  linkElement.style.padding = '0px 3px';
  linkElement.href = 'javascript:void(0);';

  /** private void initHeaderRow ( headerRow, sectionId, sectionStatus ) :: adds show/hide button **/
  function initHeaderRow (headerRow, sectionId, sectionStatus) {
    headerRow.id = 'collapsible-section_' + sectionId;
    var lastCell = headerRow.cells[headerRow.cells.length - 1];
    var link = linkElement.cloneNode(false);
    link.appendChild(document.createTextNode(sectionStatus ? linkTextHide : linkTextShow));
    $(link).click(toggleSection);

    lastCell.insertBefore(link, lastCell.firstChild);
  }

  /** private void toggleSection () :: onclick event handler **/
  function toggleSection () {
    var trHead = this.parentNode.parentNode;
    var section = sections[trHead.id.substr(20)];
    var content = section.content;
    var display = section.status ? 'none' : '';

    for (var i = 0, n = content.length; i < n; i++) {
      content[i].style.display = display;
    }

    section.status = !section.status;
    this.firstChild.data = section.status ? linkTextHide : linkTextShow;
  }

  // initialize
  var docContent = document.getElementById('bodyContent') || document.getElementById('article') || document.getElementById('mw_contentholder');
  var tables = docContent.getElementsByTagName('table');
  var sectionId = -1;

  for (var i = 0, n = tables.length; i < n; i++) {
    var classMatch = tables[i].className.match(reClassName);
    if (!classMatch) {
      continue;
    }
    var defaultStatus = classMatch[1] == classCollapsible;
    var tableRows = tables[i].rows;
    var sectionFound = false;

    for (var j = 0, m = tableRows.length; j < m; j++) {
      var classMatch = tableRows[j].className.match(reClassName);
      if (!classMatch) {
        if (sectionFound) {
          sections[sectionId].content.push(tableRows[j]);
          tableRows[j].style.display = sections[sectionId].status ? '' : 'none';
        }
        continue;
      }
      var section = {
        header: tableRows[j],
        content: [],
        status: defaultStatus ? classMatch[1] == classCollapsible : false
      };

      sectionFound = true;
      sections[++sectionId] = section;
      initHeaderRow(tableRows[j], sectionId, section.status);
    }

    if (!sectionFound) {
      var section = {
        header: tableRows[0],
        content: [],
        status: defaultStatus
      };

      for (var j = 1; j < tableRows.length; j++) {
        section.content.push(tableRows[j]);
        tableRows[j].style.display = section.status ? '' : 'none';
      }

      sections[++sectionId] = section;
      initHeaderRow(tableRows[0], sectionId, defaultStatus);
    }
  }
})(document, $);