« get me outta code hell

intrapage-dot-switcher.js « client « js « static « src - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/static/js/client/intrapage-dot-switcher.js
blob: d06bc5a6c5a9a5cc26d89f78dc545f9d8cbc759f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/* eslint-env browser */

import {stitchArrays} from '../../shared-util/sugar.js';

import {cssProp} from '../client-util.js';

export const info = {
  id: 'intrapageDotSwitcherInfo',

  // Each is a two-level array, by switcher.
  // This is an evil data structure.
  switcherSpans: null,
  switcherLinks: null,
  switcherTargets: null,
};

export function getPageReferences() {
  const switchers =
    Array.from(document.querySelectorAll('.dot-switcher.intrapage'));

  info.switcherSpans =
    switchers
      .map(switcher => switcher.querySelectorAll(':scope > span'))
      .map(spans => Array.from(spans));

  info.switcherLinks =
    info.switcherSpans
      .map(spans => spans
        .map(span => span.querySelector(':scope > a')));

  info.switcherTargets =
    info.switcherLinks
      .map(links => links
        .map(link => {
          const targetID = link.getAttribute('data-target-id');
          const target = document.getElementById(targetID);
          if (target) {
            return target;
          } else {
            console.warn(
              `An intrapage dot switcher option is targetting an ID that doesn't exist, #${targetID}`,
              link);
            link.setAttribute('inert', '');
            return null;
          }
        }));
}

export function addPageListeners() {
  for (const {links, spans, targets} of stitchArrays({
    spans: info.switcherSpans,
    links: info.switcherLinks,
    targets: info.switcherTargets,
  })) {
    for (const [index, {span, link, target}] of stitchArrays({
      span: spans,
      link: links,
      target: targets,
    }).entries()) {
      const otherSpans =
        [...spans.slice(0, index), ...spans.slice(index + 1)];

      const otherTargets =
        [...targets.slice(0, index), ...targets.slice(index + 1)];

      link.addEventListener('click', domEvent => {
        domEvent.preventDefault();

        for (const otherSpan of otherSpans) {
          otherSpan.classList.remove('current');
        }

        for (const otherTarget of otherTargets) {
          cssProp(otherTarget, 'display', 'none');
        }

        span.classList.add('current');
        cssProp(target, 'display', 'block');
      });
    }
  }
}