import * as DOM from "../services/dom"; import {scrollAndHighlightElement} from "../services/util"; class PageDisplay { constructor(elem) { this.elem = elem; this.pageId = elem.getAttribute('page-display'); window.importVersioned('code').then(Code => Code.highlight()); this.setupNavHighlighting(); this.setupDetailsCodeBlockRefresh(); // Check the hash on load if (window.location.hash) { let text = window.location.hash.replace(/\%20/g, ' ').substr(1); this.goToText(text); } // Sidebar page nav click event const sidebarPageNav = document.querySelector('.sidebar-page-nav'); if (sidebarPageNav) { DOM.onChildEvent(sidebarPageNav, 'a', 'click', (event, child) => { event.preventDefault(); window.$components.first('tri-layout').showContent(); const contentId = child.getAttribute('href').substr(1); this.goToText(contentId); window.history.pushState(null, null, '#' + contentId); }); } } goToText(text) { const idElem = document.getElementById(text); DOM.forEach('.page-content [data-highlighted]', elem => { elem.removeAttribute('data-highlighted'); elem.style.backgroundColor = null; }); if (idElem !== null) { scrollAndHighlightElement(idElem); } else { const textElem = DOM.findText('.page-content > div > *', text); if (textElem) { scrollAndHighlightElement(textElem); } } } setupNavHighlighting() { // Check if support is present for IntersectionObserver if (!('IntersectionObserver' in window) || !('IntersectionObserverEntry' in window) || !('intersectionRatio' in window.IntersectionObserverEntry.prototype)) { return; } let pageNav = document.querySelector('.sidebar-page-nav'); // fetch all the headings. let headings = document.querySelector('.page-content').querySelectorAll('h1, h2, h3, h4, h5, h6'); // if headings are present, add observers. if (headings.length > 0 && pageNav !== null) { addNavObserver(headings); } function addNavObserver(headings) { // Setup the intersection observer. let intersectOpts = { rootMargin: '0px 0px 0px 0px', threshold: 1.0 }; let pageNavObserver = new IntersectionObserver(headingVisibilityChange, intersectOpts); // observe each heading for (let heading of headings) { pageNavObserver.observe(heading); } } function headingVisibilityChange(entries, observer) { for (let entry of entries) { let isVisible = (entry.intersectionRatio === 1); toggleAnchorHighlighting(entry.target.id, isVisible); } } function toggleAnchorHighlighting(elementId, shouldHighlight) { DOM.forEach('a[href="#' + elementId + '"]', anchor => { anchor.closest('li').classList.toggle('current-heading', shouldHighlight); }); } } setupDetailsCodeBlockRefresh() { const onToggle = event => { const codeMirrors = [...event.target.querySelectorAll('.CodeMirror')]; codeMirrors.forEach(cm => cm.CodeMirror && cm.CodeMirror.refresh()); }; const details = [...this.elem.querySelectorAll('details')]; details.forEach(detail => detail.addEventListener('toggle', onToggle)); } } export default PageDisplay;