summaryrefslogtreecommitdiff
path: root/static/menu.js
diff options
context:
space:
mode:
Diffstat (limited to 'static/menu.js')
-rw-r--r--static/menu.js159
1 files changed, 159 insertions, 0 deletions
diff --git a/static/menu.js b/static/menu.js
new file mode 100644
index 0000000..a014793
--- /dev/null
+++ b/static/menu.js
@@ -0,0 +1,159 @@
+// menu.js - menu system for small site - 2022 Viljami Ilola
+
+const jsonURL = 'pages.json'
+
+var conf = {}
+var pages = {}
+var currentPage = null;
+loadPages = async() => {
+ await fetch( jsonURL )
+ .then( response => response.json() )
+ .then( json => conf = json )
+ .catch( error => {
+ document.body.innerHTML = `Error loading ${jsonURL}<hr>${error}`
+ } )
+ pages = conf.pages
+
+ installHamburger()
+ createMenu()
+ createPlaceholders()
+ hashToPage()
+}
+
+createPlaceholders = () => {
+ pagesMain = document.createElement('main')
+ Object.keys(pages).forEach(p => {
+ if ( pages[p].URL && pages[p].URL !== "" ) {
+ const pageSection = document.createElement('section')
+ pageSection.id = `${p}_page`
+ pageSection.className='page'
+ pagesMain.appendChild( pageSection )
+ }
+ })
+ document.documentElement.lastChild.append( pagesMain )
+}
+
+createMenuIcon = (p) => {
+ const icon = pages[p].menuIcon ? pages[p].menuIcon : ''
+ if ( icon === '' ) return null
+
+ const iconImg = document.createElement('img')
+ iconImg.src = icon
+
+ const iconAnchor = document.createElement('a')
+ iconAnchor.href = `#${p}`
+ iconAnchor.appendChild( iconImg )
+
+ const iconDiv = document.createElement('div')
+ iconDiv.className = 'menuIcon'
+ iconDiv.appendChild( iconAnchor )
+
+ return iconDiv
+}
+
+createMenuText = (p) => {
+ const url = pages[p].URL ? pages[p].URL : ""
+ const name = pages[p].menuName ? pages[p].menuName : url
+
+ if ( name === '' ) return null
+
+ const textNode = document.createTextNode( name )
+
+ const textAnchor = document.createElement( url === "" ? 'div' : 'a')
+ textAnchor.href = `#${p}`
+ textAnchor.appendChild( textNode )
+
+ const textDiv = document.createElement('div')
+ textDiv.className = 'menuText'
+ textDiv.appendChild( textAnchor )
+
+ return textDiv
+}
+
+createMenu = () => {
+ const menuNav = document.createElement('nav')
+ menuNav.id = 'menu'
+ menuNav.className = 'menuHidden'
+
+ Object.keys(pages).forEach(p => {
+
+ const entryDiv = document.createElement('div')
+ entryDiv.className = 'menuItem'
+ entryDiv.id = `${p}_menuEntry`
+
+ const iconDiv = createMenuIcon(p)
+ const textDiv = createMenuText(p)
+ if ( iconDiv ) entryDiv.appendChild( iconDiv )
+ if ( textDiv ) entryDiv.appendChild( textDiv )
+
+ const url = pages[p].URL ? pages[p].URL : ""
+ const name = pages[p].menuName ? pages[p].menuName : url
+ if ( url === "" ) entryDiv.className +=
+ name === "" ? ' menuSpacer' : ' menuTitle'
+ else entryDiv.onclick = () => window.location.hash = p;
+
+ menuNav.append( entryDiv )
+ })
+ document.documentElement.lastChild.append( menuNav )
+
+ const spacerDiv = document.createElement('div')
+ spacerDiv.id = 'spaceBeforePage'
+ document.documentElement.lastChild.append( spacerDiv )
+}
+
+installHamburger = () => {
+ hamburgerDiv = document.createElement('div')
+ hamburgerDiv.id = 'hamburgerMenu'
+ hamburgerDiv.onclick = () => toggleMenu()
+ document.documentElement.lastChild.append( hamburgerDiv )
+}
+
+toggleMenu = () => {
+ const menuNav = document.getElementById('menu')
+ menuNav.className = menuNav.className === 'menuHidden' ? '' : 'menuHidden'
+ if (menuNav.className === '') window.scrollTo(0,0)
+}
+
+hashToPage = () => {
+ const p = !document.location.hash
+ ? Object.keys(pages)[0] : document.location.hash.substr(1) in pages
+ ? document.location.hash.substr(1) : Object.keys(pages)[0]
+
+ if ( p === Object.keys(pages)[0] ) {
+ window.history.replaceState('', '', window.location.pathname)
+ }
+ if ( p === currentPage ) return false
+
+ const pageElement = document.getElementById(`${p}_page`)
+
+ if ( !currentPage ) currentPage = p;
+ else document.getElementById(`${currentPage}_page`).className = 'page'
+ pageElement.className = 'page pageActive'
+
+ if ( !pageElement.loaded ) fetch( pages[p].URL )
+ .then( response => {
+ if (!response.ok) return `ERROR loading "${pages[p].URL}"!`
+ return response.text()
+ } )
+ .then( text => {
+ pageElement.innerHTML = text
+ pageElement.loaded = true
+ } )
+ document.getElementById(`${currentPage}_menuEntry`)
+ .className = 'menuItem'
+ document.getElementById(`${p}_menuEntry`)
+ .className = 'menuItem menuItemActive'
+ currentPage = p
+ if (!pages[p].pageTitle) document.title = conf.title
+ else document.title = `${pages[p].pageTitle} - ${conf.title}`
+}
+
+hideMenu = () => document.getElementById('menu').className = 'menuHidden';
+
+window.onload = async() => {
+ loadPages()
+}
+window.onhashchange = () => {
+ hideMenu()
+ hashToPage()
+}