Module: Asciidoctor::Html::Flip
- Defined in:
- lib/asciidoctor/html/flip.rb
Overview
Flip when pagestyle=multipage
Constant Summary collapse
- FLIP =
<<~JS (function() { const sectSelector = '.content-container > .section'; // Holds replaced pagination links to prev/next chapter const chapPagination = { prevChap: null, nextChap: null }; // Dictionary sect ID => [all sects until next sect with ID] const sectsById = { "page": []}; const page = document.getElementById('page'); const nav = document.querySelectorAll('#sidebar nav > ul > li.active > ul > li'); let currentId = "page"; document.querySelectorAll('.content-container > .chaphead, .content-container > .preamble').forEach(el => { sectsById[currentId].push(el); el.dataset.withSect = currentId; }); document.querySelectorAll(sectSelector).forEach(el => { if(el.id) { el.dataset.prevPage = currentId; currentId = el.id; sectsById[currentId] ||= []; } const prevId = el.dataset.prevPage; if(prevId) { sectsById[prevId][0].dataset.nextPage = currentId; } sectsById[currentId].push(el); el.dataset.withSect = currentId; }); function updatePaginator(prev, next) { const paginator = document.querySelector('.paginator'); if(!paginator) return; const nextPage = paginator.lastElementChild; const prevPage = paginator.firstElementChild; if(next) { const nextLink = document.createElement('a'); nextLink.href = '#' + next.id; nextLink.innerHTML = 'Next ›'; chapPagination.nextChap ||= nextPage; nextPage.replaceWith(nextLink); } else if(chapPagination.nextChap) { nextPage.replaceWith(chapPagination.nextChap); } if(prev) { const prevLink = document.createElement('a'); prevLink.href = '#' + (prev.id ? prev.id : 'page'); prevLink.innerHTML = '‹ Previous'; chapPagination.prevChap ||= prevPage; prevPage.replaceWith(prevLink); } else if(chapPagination.prevChap) { prevPage.replaceWith(chapPagination.prevChap) } paginator.classList.add('visible'); } function flip(e) { if(!page.classList.contains('multi')) return; e && e.preventDefault(); const href = location.hash; let id = href.substring(1); const target = document.getElementById(id); if(!target) id = "page"; let section = target && target.closest(sectSelector); if(section) { id = section.dataset.withSect; section = sectsById[id][0]; } for(const key in sectsById) { if(key == id) { const firstSect = sectsById[key][0]; const prev = firstSect.dataset.prevPage && sectsById[firstSect.dataset.prevPage][0]; const next = firstSect.dataset.nextPage && sectsById[firstSect.dataset.nextPage][0]; updatePaginator(prev, next); sectsById[key].forEach(el => el.classList.add('d-block')); } else { sectsById[key].forEach(el => el.classList.remove('d-block')); } } nav.forEach(el => { const a = el.querySelector('a'); const href = a && a.getAttribute('href'); el.classList.toggle('active', id == href.substring(1)); }); ADHT.nudgeMenuBtn(); if(target == section) { page.scrollTo({ top: 0, left: 0 }); } else { const rect = target.getBoundingClientRect() page.scrollTo({ top: rect.top + page.scrollTop, left: 0 }); } } flip(); addEventListener('hashchange', flip); const layoutButton = document.getElementById('btn-layout'); layoutButton && layoutButton.addEventListener('click', function(){ const multi = page.classList.contains('multi'); layoutButton.textContent = (multi ? 'multiple pages' : 'single page'); page.classList.toggle('multi'); if(multi) { // We have switched to Single Page ADHT.nudgeMenuBtn(); } else { flip(); } }); })(); JS