--- /dev/null
+;(function () {
+ 'use strict'
+
+ var navContainer = document.querySelector('.nav-container')
+ var navToggle = document.querySelector('.nav-toggle')
+
+ navToggle.addEventListener('click', showNav)
+ // NOTE don't let click events propagate outside of nav container
+ navContainer.addEventListener('click', concealEvent)
+
+ var menuPanel = navContainer.querySelector('[data-panel=menu]')
+ if (!menuPanel) return
+ var nav = navContainer.querySelector('.nav')
+
+ var currentPageItem = menuPanel.querySelector('.is-current-page')
+ if (currentPageItem) {
+ activateCurrentPath(currentPageItem)
+ scrollItemToMidpoint(menuPanel, currentPageItem.querySelector('.nav-link'))
+ } else {
+ menuPanel.scrollTop = 0
+ }
+
+ find(menuPanel, '.nav-item-toggle').forEach(function (btn) {
+ var li = btn.parentElement
+ btn.addEventListener('click', toggleActive.bind(li))
+ var navItemSpan = findNextElement(btn, '.nav-text')
+ if (navItemSpan) {
+ navItemSpan.style.cursor = 'pointer'
+ navItemSpan.addEventListener('click', toggleActive.bind(li))
+ }
+ })
+
+ nav.querySelector('.context').addEventListener('click', function () {
+ var currentPanel = nav.querySelector('.is-active[data-panel]')
+ var activatePanel = currentPanel.dataset.panel === 'menu' ? 'explore' : 'menu'
+ currentPanel.classList.toggle('is-active')
+ nav.querySelector('[data-panel=' + activatePanel + ']').classList.toggle('is-active')
+ })
+
+ // NOTE prevent text from being selected by double click
+ menuPanel.addEventListener('mousedown', function (e) {
+ if (e.detail > 1) e.preventDefault()
+ })
+
+ function activateCurrentPath (navItem) {
+ var ancestorClasses
+ var ancestor = navItem.parentNode
+ while (!(ancestorClasses = ancestor.classList).contains('nav-menu')) {
+ if (ancestor.tagName === 'LI' && ancestorClasses.contains('nav-item')) {
+ ancestorClasses.add('is-active', 'is-current-path')
+ }
+ ancestor = ancestor.parentNode
+ }
+ navItem.classList.add('is-active')
+ }
+
+ function toggleActive () {
+ this.classList.toggle('is-active')
+ }
+
+ function showNav (e) {
+ if (navToggle.classList.contains('is-active')) return hideNav(e)
+ document.documentElement.classList.add('is-clipped--nav')
+ navToggle.classList.add('is-active')
+ navContainer.classList.add('is-active')
+ window.addEventListener('click', hideNav)
+ concealEvent(e)
+ }
+
+ function hideNav (e) {
+ if (e.which === 3 || e.button === 2) return
+ document.documentElement.classList.remove('is-clipped--nav')
+ navToggle.classList.remove('is-active')
+ navContainer.classList.remove('is-active')
+ window.removeEventListener('click', hideNav)
+ concealEvent(e)
+ }
+
+ // NOTE don't let event get picked up by window click listener
+ function concealEvent (e) {
+ e.stopPropagation()
+ }
+
+ function scrollItemToMidpoint (panel, el) {
+ var rect = panel.getBoundingClientRect()
+ var effectiveHeight = rect.height
+ var navStyle = window.getComputedStyle(nav)
+ if (navStyle.position === 'sticky') effectiveHeight -= (rect.top - parseFloat(navStyle.top))
+ panel.scrollTop = Math.max(0, (el.getBoundingClientRect().height - effectiveHeight) * 0.5 + el.offsetTop)
+ }
+
+ function find (from, selector) {
+ return [].slice.call(from.querySelectorAll(selector))
+ }
+
+ function findNextElement (from, selector) {
+ var el
+ if ('nextElementSibling' in from) {
+ el = from.nextElementSibling
+ } else {
+ el = from
+ while ((el = el.nextSibling) && el.nodeType !== 1);
+ }
+ return el && selector ? el[el.matches ? 'matches' : 'msMatchesSelector'](selector) && el : el
+ }
+})()
+++ /dev/null
-;(function () {
- 'use strict'
-
- var navContainer = document.querySelector('.nav-container')
- var navToggle = document.querySelector('.nav-toggle')
-
- navToggle.addEventListener('click', toggleNavigation)
- // don't let click events propagate outside of nav container
- navContainer.addEventListener('click', concealEvent)
-
- var menuPanel = navContainer.querySelector('[data-panel=menu]')
- if (!menuPanel) return
-
- var navState = getNavState()
- var menuState = getMenuState(navState, navContainer.dataset.component, navContainer.dataset.version)
-
- navContainer.querySelector('.context').addEventListener('click', function () {
- var currentPanel = navContainer.querySelector('.is-active[data-panel]')
- var activatePanel = currentPanel.dataset.panel === 'menu' ? 'explore' : 'menu'
- currentPanel.classList.toggle('is-active')
- navContainer.querySelector('[data-panel=' + activatePanel + ']').classList.toggle('is-active')
- })
-
- find('.nav-item-toggle', menuPanel).forEach(function (btn) {
- var li = btn.parentElement
- btn.addEventListener('click', function () {
- li.classList.toggle('is-active')
- menuState.expandedItems = getExpandedItems()
- saveNavState()
- })
- var navItemSpan = findNextElement(btn, '.nav-text')
- if (navItemSpan) {
- navItemSpan.style.cursor = 'pointer'
- navItemSpan.addEventListener('click', function () {
- li.classList.toggle('is-active')
- menuState.expandedItems = getExpandedItems()
- saveNavState()
- })
- }
- })
-
- find('.nav-item', menuPanel).forEach(function (item, idx) {
- item.setAttribute('data-id', 'menu-' + item.dataset.depth + '-' + idx)
- })
-
- var expandedItems = menuState.expandedItems || (menuState.expandedItems = [])
-
- if (expandedItems.length) {
- find(
- expandedItems
- .map(function (itemId) {
- return '.nav-item[data-id="' + itemId + '"]'
- })
- .join(','),
- menuPanel
- ).forEach(function (item) {
- item.classList.add('is-active')
- })
- }
-
- var currentPageItem = menuPanel.querySelector('.is-current-page')
- if (currentPageItem) {
- activateCurrentPath(currentPageItem).forEach(function (itemId) {
- if (expandedItems.indexOf(itemId) < 0) expandedItems.push(itemId)
- })
- }
-
- saveNavState()
-
- scrollItemIntoView(menuState.scroll || 0, menuPanel, currentPageItem && currentPageItem.querySelector('.nav-link'))
-
- menuPanel.addEventListener('scroll', function () {
- menuState.scroll = Math.round(menuPanel.scrollTop)
- saveNavState()
- })
-
- function activateCurrentPath (navItem) {
- var ids = [navItem.dataset.id]
- var ancestorClasses
- var ancestor = navItem.parentNode
- while (!(ancestorClasses = ancestor.classList).contains('nav-menu')) {
- if (ancestor.tagName === 'LI' && ancestorClasses.contains('nav-item')) {
- ancestorClasses.add('is-active', 'is-current-path')
- ids.push(ancestor.dataset.id)
- }
- ancestor = ancestor.parentNode
- }
- navItem.classList.add('is-active')
- return ids
- }
-
- function toggleNavigation (e) {
- if (navToggle.classList.contains('is-active')) return closeNavigation(e)
- document.documentElement.classList.add('is-clipped--nav')
- navToggle.classList.add('is-active')
- navContainer.classList.add('is-active')
- window.addEventListener('click', closeNavigation)
- // don't let this event get picked up by window click listener
- concealEvent(e)
- }
-
- function closeNavigation (e) {
- if (e.which === 3 || e.button === 2) return
- document.documentElement.classList.remove('is-clipped--nav')
- navToggle.classList.remove('is-active')
- navContainer.classList.remove('is-active')
- window.removeEventListener('click', closeNavigation)
- // don't let this event get picked up by window click listener
- concealEvent(e)
- }
-
- function concealEvent (e) {
- e.stopPropagation()
- }
-
- function getExpandedItems () {
- return find('.is-active', menuPanel).map(function (item) {
- return item.dataset.id
- })
- }
-
- function getNavState () {
- var data = window.sessionStorage.getItem('nav-state')
- return data && (data = JSON.parse(data)).__version__ === '1' ? data : { __version__: '1' }
- }
-
- function getMenuState (navState, component, version) {
- var key = version + '@' + component
- return navState[key] || (navState[key] = {})
- }
-
- function saveNavState () {
- window.sessionStorage.setItem('nav-state', JSON.stringify(navState))
- }
-
- function scrollItemIntoView (scrollPosition, parent, el) {
- if (!el) return (parent.scrollTop = scrollPosition)
-
- var margin = 10
- //var y = el.getBoundingClientRect().top - parent.getBoundingClientRect().top
- var y = el.offsetTop
-
- if (y < scrollPosition) {
- parent.scrollTop = y - margin
- } else if (y - parent.offsetHeight + el.offsetHeight > scrollPosition) {
- parent.scrollTop = y - parent.offsetHeight + el.offsetHeight + margin
- } else {
- parent.scrollTop = scrollPosition
- }
- }
-
- function find (selector, from) {
- return [].slice.call((from || document).querySelectorAll(selector))
- }
-
- function findNextElement (from, selector) {
- var el
- if ('nextElementSibling' in from) {
- el = from.nextElementSibling
- } else {
- el = from
- while ((el = el.nextSibling) && el.nodeType !== 1);
- }
- return el && selector ? el[el.matches ? 'matches' : 'msMatchesSelector'](selector) && el : el
- }
-})()