Source: components/dynamic-sidebar/_dynamic-sidebar.js

'use strict';

/**
 * Dynamic sidebar.
 * @namespace dynamicSidebar
 * @memberof UCASDesignFramework
 * @param {object} global - UCASDesignFramework object.
 * @param {object} _u - UCASUtilities object.
 */
(function (global, _u) {
  var content
  var contentHeader
  var dynamicSidebarContainer
  var dynamicSidebar
  var dynamicSidebarInner
  var dynamicSidebarLabel
  var dynamicSidebarOpenButton
  var dynamicSidebarCloseButton
  var dynamicSidebarPrepared = false
  var resizeTimeout
  var clientWidth

  /**
   * Initialise the dynamic sidebar.
   * @function init
   * @memberof! UCASDesignFramework.dynamicSidebar
   * @public
   */
  function init () {
    dynamicSidebarContainer = document.querySelector('.dynamic-sidebar-container')
    dynamicSidebar = document.querySelector('.dynamic-sidebar-container .dynamic-sidebar') || document.querySelector('.dynamic-sidebar-container .section__sidebar-first')
    dynamicSidebarInner = document.querySelector('.dynamic-sidebar-container .dynamic-sidebar__inner') || document.querySelector('.dynamic-sidebar-container .region--sidebar-first') // Allow for ucas.com markup.
    content = document.querySelector('.dynamic-sidebar-container .section__content')

    if (content === null || dynamicSidebar === null || dynamicSidebarContainer === null || dynamicSidebarInner === null) {
      return
    }

    clientWidth = document.body.clientWidth
    prepareDynamicSidebar(calculateScreenSize())

    window.addEventListener('resize', resizeThrottler, false)
  }

  /**
   * Slow down the resize handler so we don't repaint too much.
   * @TODO This can be generalised and put into _size.js
   */
  function resizeThrottler () {
    if (!resizeTimeout) {
      resizeTimeout = setTimeout(function () {
        resizeTimeout = null

        // Check width as triggering the keyboard on Android changes page size.
        // We're only interested if the width changes.
        if (clientWidth !== document.body.clientWidth) {
          clientWidth = document.body.clientWidth
          prepareDynamicSidebar(calculateScreenSize())
        }
      }, 100)
    }
  }

  /**
   * Decide how to display the sidebar.
   * @return {string} - mobile|desktop
   */
  function calculateScreenSize () {
    return global.size.cssBreakpoint === 'medium' || global.size.cssBreakpoint === 'small' || global.size.cssBreakpoint === 'xsmall' ? 'mobile' : 'desktop'
  }

  /**
   * Create the open button if it doesn't already exist.
   * @function createOpenButton
   * @memberof! UCASDesignFramework.dynamicSidebar
   * @public
   */
  function createOpenButton () {
    // First create the sectionHeader if it doesn't exist.
    contentHeader = content.querySelector('.content-header')
    // Add the trigger button.
    if (!dynamicSidebarOpenButton) {
      if (!contentHeader) {
        contentHeader = document.createElement('header')
        contentHeader.setAttribute('class', 'content-header')
        content.insertBefore(contentHeader, content.firstChild)
      }
      // Create the trigger button.
      dynamicSidebarLabel = dynamicSidebar.getAttribute('data-dynamic-sidebar-label') || 'sidebar'
      dynamicSidebarOpenButton = document.createElement('button')
      dynamicSidebarOpenButton.setAttribute('class', 'button icon-inline--left icon--filter-dark')
      dynamicSidebarOpenButton.setAttribute('id', 'dynamic-sidebar-open-button')
      dynamicSidebarOpenButton.appendChild(document.createTextNode('Show ' + dynamicSidebarLabel))
      contentHeader.insertBefore(dynamicSidebarOpenButton, contentHeader.firstChild)
      UCASUtilities.toggle.create(
        'dynamic-sidebar-open-button',
        function () {
          document.documentElement.style.overflow = 'hidden'
          document.querySelector('.section--content').style.zIndex = '10'
          document.documentElement.setAttribute('data-dynamic-sidebar', 'open')
        },
        function () {
          document.documentElement.style.overflow = ''
          document.documentElement.setAttribute('data-dynamic-sidebar', 'closed')
          setTimeout(function () {
            document.querySelector('.section--content').style.zIndex = ''
          }, 800)
        },
        false
      )
    // If the button already exists.
    } else {
      // But does not exist as part of the visible DOM.
      if (!document.getElementById('dynamic-sidebar-open-button')) {
        // Reinsert it.
        contentHeader.insertBefore(dynamicSidebarOpenButton, contentHeader.firstChild)
      }
    }
  }

  /**
   * Create the close button if it doesn't already exist.
   * @function createCloseButton
   * @memberof! UCASDesignFramework.dynamicSidebar
   * @public
   */
  function createCloseButton () {
    if (!dynamicSidebarCloseButton) {
      // Create the close button.
      dynamicSidebarLabel = dynamicSidebar.getAttribute('data-dynamic-sidebar-label') || 'sidebar'
      dynamicSidebarCloseButton = document.createElement('button')
      dynamicSidebarCloseButton.setAttribute('class', 'button button--modal-close')
      dynamicSidebarCloseButton.appendChild(document.createTextNode('Hide ' + dynamicSidebarLabel))
      var searchFiltersCloseContainer = document.createElement('div')
      searchFiltersCloseContainer.setAttribute('class', 'modal-close-container')
      searchFiltersCloseContainer.appendChild(dynamicSidebarCloseButton)
      dynamicSidebar.insertBefore(searchFiltersCloseContainer, dynamicSidebar.firstChild)
      dynamicSidebarCloseButton.addEventListener('click', function (e) {
        e.preventDefault()
        _u.toggle.hide('dynamic-sidebar-open-button')
        document.documentElement.setAttribute('data-dynamic-sidebar-closing', '')
        setTimeout(function () {
          document.documentElement.removeAttribute('data-dynamic-sidebar-closing')
        }, 800)
      })
    }
  }

  /**
   * Render the sidebar.
   * @param {string} screenSize - mobile|desktop
   */
  function prepareDynamicSidebar (screenSize) {
    if (screenSize === 'mobile' && !dynamicSidebarPrepared) {
      // Set state.
      document.documentElement.setAttribute('data-dynamic-sidebar', 'closed')
      createOpenButton()
      createCloseButton()

      // Set state.
      dynamicSidebarPrepared = true
    } else if (screenSize === 'desktop') {
      if (dynamicSidebarPrepared) {
        // Toggle the sidebar closed if open.
        _u.toggle.hide('dynamic-sidebar-open-button')
        // Remove the trigger button.
        if (dynamicSidebarOpenButton) {
          contentHeader.removeChild(dynamicSidebarOpenButton)
          dynamicSidebarOpenButton = null
        }

        // Set state.
        dynamicSidebarPrepared = false
      }
    }
  }

  /**
   * Assign public methods.
   */
  global.dynamicSidebar = {
    init: init,
    createOpenButton: createOpenButton,
    createCloseButton: createCloseButton
  }
})(UCASDesignFramework, UCASUtilities)