{"version":3,"file":"app/modal.js","sources":["modal.js"],"sourcesContent":["/*----------------------------------------------------------------------------*\\\r\n MODAL\r\n Opening and closing an accessible modal, as per https://github.com/gdkraus/accessible-modal-dialog\r\n \\*----------------------------------------------------------------------------*/\r\n\r\n/**\r\n * Use strict as per:\r\n * http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/\r\n */\r\n'use strict';\r\n\r\n\r\n/**\r\n * Check if oy object exists, otherwise create it\r\n */\r\nvar oy = oy || {};\r\n\r\n\r\n/**\r\n * Jshint global references\r\n * Please define all third party plugins that you use to not break jshinting\r\n */\r\n\r\n\r\n\r\n/* Component\r\n \\*----------------------------------------------------------------------------*/\r\n\r\noy.modal = {\r\n $mainPage: document.querySelector('.js--main-page'),\r\n $modalOverlay: document.querySelector('.js--modal-overlay'),\r\n $modals: document.querySelectorAll('.js--modal'),\r\n $triggersOpenModal: document.querySelectorAll('.js--open-modal'),\r\n $triggersCloseModal: document.querySelectorAll('.js--close-modal'),\r\n focusableElementsString: 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]',\r\n // store the item that has focus before opening the modal window\r\n focusedElementBeforeModal: null,\r\n $activeModal: null,\r\n\r\n init: function () {\r\n if (oy.cutsMustard) {\r\n this.initModal(document);\r\n }\r\n },\r\n\r\n initModal: function ($context) {\r\n var self = this;\r\n\r\n self.moveModals($context);\r\n\r\n // bind clicks to open modal\r\n for (var i = 0; i < self.$triggersOpenModal.length; ++i) {\r\n var $openTrigger = self.$triggersOpenModal[i];\r\n $openTrigger.addEventListener('click', function () {\r\n var $modalID = this.dataset.modalId;\r\n self.openModal($context, $modalID);\r\n });\r\n }\r\n\r\n // bind clicks to close modal\r\n for (var j = 0; j < self.$triggersCloseModal.length; ++j) {\r\n var $closeTrigger = self.$triggersCloseModal[j];\r\n $closeTrigger.addEventListener('click', function () {\r\n var $modalID = this.dataset.modalId;\r\n self.closeModal($context, $modalID);\r\n });\r\n }\r\n },\r\n\r\n // move modals to the page, outside of .js--main-page\r\n moveModals: function ($context) {\r\n var self = this;\r\n for (var i = 0; i < self.$modals.length; ++i) {\r\n $context.querySelector('body').appendChild(self.$modals[i]);\r\n }\r\n },\r\n\r\n openModal: function ($context, $modalID, message, buttons, title) {\r\n var self = this,\r\n $modal = $context.getElementById($modalID);\r\n self.$activeModal = $modal;\r\n\r\n self.updatePosition();\r\n // mark the main page as hidden\r\n self.$mainPage.setAttribute('aria-hidden', 'true');\r\n // insert an overlay to prevent clicking and make a visual change to indicate the main apge is not available\r\n self.$modalOverlay.classList.add('is-open');\r\n // open the modal, set state\r\n $modal.classList.add('is-open');\r\n $modal.setAttribute('aria-hidden', 'false');\r\n // prevent focus in any element outside modal\r\n self.$mainPage.addEventListener('focusin', function () {\r\n self.setFocusToFirstItemInModal($modal);\r\n });\r\n // store focused element before opening modal\r\n self.focusedElementBeforeModal = $context.querySelector(':focus');\r\n self.setFocusToFirstItemInModal($modal);\r\n // add key-bindings (tab/esc)\r\n $modal.addEventListener('keydown', function (event) {\r\n self.trapKeys($context, $modalID, event);\r\n });\r\n\r\n // set a dynamic message\r\n if (message) {\r\n $modal.querySelector('.js--message').innerHTML = '
' + message + '
';\r\n }\r\n\r\n if (title) {\r\n $modal.querySelector('.js--modal__title').innerHTML = title;\r\n }\r\n\r\n // set dynamic buttons\r\n if (buttons) {\r\n var $buttonTemplate = $modal.querySelector('.js--modal__dynamic-button-template');\r\n var $buttonWrap = $modal.querySelector('.js--modal__dynamic-button-wrap');\r\n\r\n // empty the wrapper\r\n while ($buttonWrap.firstChild) {\r\n $buttonWrap.removeChild($buttonWrap.firstChild);\r\n }\r\n\r\n // re-add the template\r\n $buttonWrap.appendChild($buttonTemplate);\r\n\r\n // append buttons, attach actions\r\n for (var i = 0; i < buttons.length; ++i) {\r\n var button = buttons[i];\r\n var $clone = $buttonTemplate.cloneNode(true);\r\n var $button = $clone.querySelector('.js--modal__dynamic-button');\r\n $button.innerHTML = button.text;\r\n $button.addEventListener('click', button.action);\r\n $clone.classList.remove('u-visuallyhidden');\r\n $buttonWrap.appendChild($clone);\r\n }\r\n }\r\n },\r\n\r\n trapKeys: function ($context, $modalID, event) {\r\n var self = this,\r\n $modal = $context.getElementById($modalID);\r\n\r\n // if escape pressed\r\n if (event.which === 27) {\r\n self.closeModal($context, $modalID);\r\n }\r\n\r\n // if tab or shift-tab pressed\r\n if (event.which === 9) {\r\n // get list of focusable items\r\n var focusableItems = $modal.querySelectorAll(self.focusableElementsString),\r\n // get currently focused item\r\n focusedItem = $context.querySelector(':focus');\r\n\r\n // get the number of focusable items\r\n var numberOfFocusableItems = focusableItems.length;\r\n\r\n // get the index of the currently focused item\r\n var focusedItemIndex = Array.prototype.indexOf.call(focusableItems, focusedItem);\r\n\r\n if (event.shiftKey) {\r\n //back tab\r\n // if focused on first item and user preses back-tab, go to the last focusable item\r\n if (focusedItemIndex === 0) {\r\n focusableItems[numberOfFocusableItems - 1].focus();\r\n event.preventDefault();\r\n }\r\n\r\n } else {\r\n //forward tab\r\n // if focused on the last item and user preses tab, go to the first focusable item\r\n if (focusedItemIndex === numberOfFocusableItems - 1) {\r\n focusableItems[0].focus();\r\n event.preventDefault();\r\n }\r\n }\r\n }\r\n },\r\n\r\n setFocusToFirstItemInModal: function ($modal) {\r\n var self = this;\r\n // set the focus to the first keyboard focusable item, but skip elements which have class=\"js--skip-initial-focus\"\r\n var $focusableElements = $modal.querySelectorAll(self.focusableElementsString);\r\n for (var i = 0; i < $focusableElements.length; i++) {\r\n if (!$focusableElements[i].classList.contains('js--skip-initial-focus')) {\r\n $focusableElements[i].focus();\r\n return;\r\n }\r\n }\r\n },\r\n\r\n closeModal: function ($context, $modalID) {\r\n var self = this,\r\n $modal = $context.getElementById($modalID);\r\n\r\n if($modal === null){\r\n return;\r\n }\r\n\r\n self.$activeModal = null;\r\n\r\n // hide overlay\r\n self.$modalOverlay.classList.remove('is-open');\r\n // hide modal\r\n $modal.classList.remove('is-open');\r\n // set states\r\n $modal.setAttribute('aria-hidden', 'true');\r\n self.$mainPage.setAttribute('aria-hidden', 'false');\r\n // remove the listener which redirects tab keys in the main content area to the modal\r\n $context.removeEventListener('focusin', self.$mainPage);\r\n // set focus back to element that had it before the modal was opened\r\n if (self.focusedElementBeforeModal) {\r\n self.focusedElementBeforeModal.focus();\r\n }\r\n },\r\n\r\n updatePosition: function () {\r\n var self = this;\r\n if (self.$activeModal && oy.embedding.isEnabled) {\r\n window.requestAnimationFrame(function(){\r\n if (oy.embedding.child.parentViewportHeight <= oy.embedding.child.frameHeight) {\r\n var modalCenterFromTop = (oy.embedding.child.parentScrollTop - oy.embedding.child.parentFramePosition) + (oy.embedding.child.parentViewportHeight/2);\r\n var top = modalCenterFromTop - self.$activeModal.offsetHeight/2;\r\n if (oy.embedding.child.parentScrollTop <= oy.embedding.child.parentFramePosition) {\r\n top = oy.settings.space;\r\n }\r\n self.$activeModal.style.top = top + 'px';\r\n }\r\n });\r\n }\r\n }\r\n};\r\n\r\n\r\nwindow.addEventListener(oy.settings.embedScrollChangeName, function () {\r\n oy.modal.updatePosition();\r\n}, false);\r\n\r\n\r\nwindow.addEventListener('load', function () {\r\n oy.modal.init();\r\n}, false);\r\n"],"names":[],"mappings":"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","sourceRoot":"/source/"}