|
| 1 | +class ToggleSection { |
| 2 | + TOGGLE_CLASS = 'toggle-section'; |
| 3 | + TOGGLE_ICON_SHOW = ['fa-solid', 'fa-eye']; |
| 4 | + TOGGLE_ICON_HIDE = ['fa-solid', 'fa-eye-slash']; |
| 5 | + TOGGLE_TITLE_SHOW = 'Show Section'; |
| 6 | + TOGGLE_TITLE_HIDE = 'Hide section'; |
| 7 | + TOGGLE_ALL_SECTIONS_SELECTOR = '.toggle-all-sections'; |
| 8 | + TOGGLE_ALL_SECTIONS_TITLE_SHOW = 'Expand all sections'; |
| 9 | + TOGGLE_ALL_SECTIONS_TITLE_HIDE = 'Collapse all sections'; |
| 10 | + sections = []; |
| 11 | + |
| 12 | + |
| 13 | + constructor() { |
| 14 | + this.sectionHeadings = document.querySelectorAll('section > h2,h3,h4,h5,h6'); |
| 15 | + this.sectionHeadings.forEach(heading => { |
| 16 | + const toggleSectionButton = this.createToggleSectionButton() |
| 17 | + const headerLink = heading.querySelector('a.headerlink'); |
| 18 | + const section = heading.parentElement; |
| 19 | + this.sections.push(section) |
| 20 | + heading.insertBefore(toggleSectionButton, headerLink); |
| 21 | + toggleSectionButton.addEventListener('click', (e) => { |
| 22 | + e.preventDefault() |
| 23 | + this.toggleSection(section) |
| 24 | + }) |
| 25 | + }) |
| 26 | + if (this.sectionHeadings) { |
| 27 | + const links = document.querySelectorAll('a') |
| 28 | + links.forEach(link => { |
| 29 | + if (link.hash) { |
| 30 | + link.addEventListener('click', (e) => { |
| 31 | + const section = document.querySelector(link.hash) |
| 32 | + if (section) { |
| 33 | + this.changeSection(section, false) |
| 34 | + } |
| 35 | + }) |
| 36 | + } |
| 37 | + }) |
| 38 | + } |
| 39 | + const toggleAllSectionsButton = document.querySelector(this.TOGGLE_ALL_SECTIONS_SELECTOR) |
| 40 | + if (toggleAllSectionsButton) { |
| 41 | + toggleAllSectionsButton.addEventListener('click', () => { |
| 42 | + toggleAllSectionsButton.classList.toggle('hide-all') |
| 43 | + const hideAll = toggleAllSectionsButton.classList.contains('hide-all') |
| 44 | + toggleAllSectionsButton.setAttribute('title', hideAll ? this.TOGGLE_ALL_SECTIONS_TITLE_SHOW : this.TOGGLE_ALL_SECTIONS_TITLE_HIDE); |
| 45 | + toggleAllSectionsButton.textContent = hideAll ? this.TOGGLE_ALL_SECTIONS_TITLE_SHOW : this.TOGGLE_ALL_SECTIONS_TITLE_HIDE; |
| 46 | + this.sections.forEach(section => { |
| 47 | + this.changeSection(section, hideAll) |
| 48 | + }) |
| 49 | + }) |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + createToggleSectionButton() { |
| 54 | + const toggleButton = document.createElement('a') |
| 55 | + toggleButton.classList.add(this.TOGGLE_CLASS); |
| 56 | + toggleButton.setAttribute('href', '#'); |
| 57 | + toggleButton.setAttribute('title', this.TOGGLE_TITLE_HIDE); |
| 58 | + const icon = document.createElement('i'); |
| 59 | + icon.classList.add(...this.TOGGLE_ICON_HIDE); |
| 60 | + toggleButton.appendChild(icon); |
| 61 | + return toggleButton; |
| 62 | + } |
| 63 | + |
| 64 | + toggleSection(section) { |
| 65 | + const isCollapsed = section.classList.contains('section-collapsed'); |
| 66 | + this.changeSection(section, !isCollapsed) |
| 67 | + } |
| 68 | + |
| 69 | + changeSection(section, hide) { |
| 70 | + if (hide) { |
| 71 | + section.classList.add('section-collapsed'); |
| 72 | + } else { |
| 73 | + section.classList.remove('section-collapsed'); |
| 74 | + } |
| 75 | + const headings = ['H2', 'H3', 'H4', 'H5', 'H6']; |
| 76 | + section.querySelectorAll(':scope > *').forEach(sectionEl => { |
| 77 | + if (headings.includes(sectionEl.nodeName)) { |
| 78 | + const toggle = sectionEl.querySelector('.' + this.TOGGLE_CLASS); |
| 79 | + const icon = toggle.querySelector(':scope > i'); |
| 80 | + toggle.setAttribute('title', hide ? this.TOGGLE_TITLE_SHOW : this.TOGGLE_TITLE_HIDE); |
| 81 | + icon.classList.remove(...icon.classList); |
| 82 | + const classesToAdd = hide ? this.TOGGLE_ICON_SHOW : this.TOGGLE_ICON_HIDE; |
| 83 | + icon.classList.add(...classesToAdd); |
| 84 | + } else { |
| 85 | + if (hide) { |
| 86 | + sectionEl.classList.add('collapsed-section-content'); |
| 87 | + } else { |
| 88 | + sectionEl.classList.remove('collapsed-section-content'); |
| 89 | + } |
| 90 | + } |
| 91 | + }) |
| 92 | + } |
| 93 | +} |
| 94 | + |
| 95 | + |
| 96 | +new ToggleSection() |
0 commit comments