'use strict';
/**
* Breadcrumb component.
* @namespace breadcrumb
* @memberof UCASDesignFramework
* @param {object} global - UCASDesignFramework object.
* @param {object} _u - UCASUtilities object.
*/
(function (global, _u) {
var breadcrumb
var mobileBreadcrumb
/**
* Initialises the first breadcrumb it finds.
* @function init
* @memberof! UCASDesignFramework.breadcrumb
* @param {Node} [context=document] - context to limit the selector
* @param {String} [selector=.breadcrumb] - a valid CSS selector for the password toggle data attribute
* @returns {Boolean} - true for success
* @example
* UCASDesignFramework.breadcrumb.init()
*/
function init (context, selector) {
// Clean up an existing breadcrumb.
destroy()
context = context || document
selector = selector || '.breadcrumb'
breadcrumb = context.querySelector(selector)
if (!breadcrumb) {
_u.log.info('Failed to find a breadcrumb')
return false
} else {
if (breadcrumb.getAttribute('data-breadcrumb') === 'initialised') {
_u.log.info('Breadcrumb already initialised')
return
}
if ((calculateScreenSize() === 'mobile') && !(breadcrumb.getAttribute('data-breadcrumb') === 'initialised')) {
createMobileBreadcrumb(breadcrumb)
}
window.addEventListener('dfResize', breadcrumbResizeHandler, false)
}
return true
}
/**
* Resize handler.
* @param {Event} event - the DOM event
*/
function breadcrumbResizeHandler () {
if ((calculateScreenSize() === 'mobile') &&
breadcrumb &&
!(breadcrumb.getAttribute('data-breadcrumb') === 'initialised')) {
createMobileBreadcrumb(breadcrumb)
} else if (
(calculateScreenSize() === 'desktop') &&
mobileBreadcrumb &&
breadcrumb &&
(breadcrumb.getAttribute('data-breadcrumb') === 'initialised')) {
destroyMobileBreadcrumb()
}
}
/**
* Decide when to display the mobile breadcrumb.
* @return {string} - mobile|desktop
*/
function calculateScreenSize () {
return global.size.cssBreakpoint === 'xsmall' ? 'mobile' : 'desktop'
}
/**
* Creates mobile breadcrumb.
* @function createMobileBreadcrumb
* @memberof! UCASDesignFramework.breadcrumb
* @param {Node} breadcrumb - the breadcrumb
*/
function createMobileBreadcrumb (breadcrumb) {
breadcrumb.setAttribute('data-breadcrumb', 'initialised')
var links = []
var breadcrumbList = document.querySelector('.breadcrumb ol')
// Iterate and get the urls of the breadcrumb.
_u.forEach(document.querySelectorAll('.breadcrumb ol li:not(:last-of-type) a'), function (i, el) {
links.push({
name: el.innerText,
url: el.getAttribute('href')
})
})
// Make home icon visible if there are only 2 links present
if (links.length <= 1 && calculateScreenSize() === 'mobile') {
return
}
var mobileBreadcrumbIcon = document.createElement('li')
var mobileBreadcrumbButton = document.createElement('button')
// Append the breadcrumb icon.
mobileBreadcrumbButton.setAttribute('aria-label', 'View breadcrumb links')
mobileBreadcrumbButton.classList.add('mobile-breadcrumb__button')
mobileBreadcrumbIcon.classList.add('mobile-breadcrumb-anchor')
mobileBreadcrumbIcon.appendChild(mobileBreadcrumbButton)
breadcrumbList.insertBefore(mobileBreadcrumbIcon, breadcrumbList.firstChild)
// Add the mobile breadcrumb.
mobileBreadcrumb = document.createElement('div')
mobileBreadcrumb.classList.add('mobile-breadcrumb')
mobileBreadcrumb.setAttribute('data-mobile-breadcrumb-hidden', 'true')
var mobileBreadcrumbList = document.createElement('ul')
mobileBreadcrumbList.classList.add('mobile-breadcrumb__wrapper')
mobileBreadcrumb.appendChild(mobileBreadcrumbList)
breadcrumb.parentNode.insertBefore(mobileBreadcrumb, breadcrumb.nextSibling)
var mobileWrapper = document.querySelector('.mobile-breadcrumb__wrapper')
// Add all of the urls to the mobile breadcrumb (in reverse).
_u.forEach(links.slice().reverse(), function (i, el) {
var mobileBreadcrumbListItem = document.createElement('li')
mobileBreadcrumbListItem.classList.add('mobile-breadcrumb__item')
var mobileBreadcrumbLink = document.createElement('a')
mobileBreadcrumbLink.setAttribute('href', el.url)
mobileBreadcrumbLink.innerText = el.name
mobileBreadcrumbListItem.appendChild(mobileBreadcrumbLink)
mobileWrapper.appendChild(mobileBreadcrumbListItem)
})
// Add the click handler.
mobileBreadcrumbButton.addEventListener('click', function (event) {
if (mobileBreadcrumb.getAttribute('data-mobile-breadcrumb-hidden') === 'true') {
mobileBreadcrumb.setAttribute('data-mobile-breadcrumb-hidden', 'false')
} else {
mobileBreadcrumb.setAttribute('data-mobile-breadcrumb-hidden', 'true')
}
event.stopPropagation()
document.addEventListener('click', breadcrumbHandler, false)
}, false)
}
/**
* Destroys mobile breadcrumb.
* @function createMobileBreadcrumb
* @memberof! UCASDesignFramework.breadcrumb
*/
function destroyMobileBreadcrumb () {
if (mobileBreadcrumb) {
mobileBreadcrumb.parentNode.removeChild(mobileBreadcrumb)
mobileBreadcrumb = null
}
var mobileBreadcrumbIcon = document.querySelector('.mobile-breadcrumb-anchor')
if (mobileBreadcrumbIcon) {
mobileBreadcrumbIcon.parentNode.removeChild(mobileBreadcrumbIcon)
}
if (breadcrumb) {
breadcrumb.removeAttribute('data-breadcrumb')
}
}
/**
* Click handler when anywhere other than the mobile breadcrumb is clicked.
* @param {Event} event - the DOM event
*/
function breadcrumbHandler (event) {
if (mobileBreadcrumb && (!event.target.classList.contains('mobile-breadcrumb')) && (!mobileBreadcrumb.contains(event.target))) {
mobileBreadcrumb.setAttribute('data-mobile-breadcrumb-hidden', 'true')
document.removeEventListener('click', breadcrumbHandler, false)
}
}
/**
* @function destroy
* @memberof! UCASDesignFramework.breadcrumb
* @example
* UCASDesignFramework.breadcrumb.destroy()
*/
function destroy () {
destroyMobileBreadcrumb()
breadcrumb = null
document.removeEventListener('click', breadcrumbHandler, false)
window.removeEventListener('dfResize', breadcrumbResizeHandler, false)
}
// Expose public methods and properties.
global.breadcrumb = {
addSubscriptions: true,
init: init,
initOnLoad: true,
destroy: destroy
}
})(UCASDesignFramework, UCASUtilities)