media/js/careers/testimonials-modal.es6.js (159 lines of code) (raw):
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
const modalContainers = document.getElementsByClassName('has-modal');
const content = document.querySelector('.mzp-u-modal-content');
const articleArray = document.querySelectorAll('[data-modal-id]');
content.classList.add('c-careers-full-testimonial-content');
// Setting up directional buttons
const modalNextButtonFragment = `<div class="c-modal-next">
<button type="button" class="c-modal-button-next" title="Next">
Next
</button>
</div>`;
const modalPrevButtonFragment = `<div class="c-modal-prev">
<button type="button" class="c-modal-button-prev" title="Previous">
Previous
</button>
</div>`;
// Set to true when a listener it set, as to not set it multiple times.
// Resets when the modal is closed.
let kbInit = null;
function keyboardListenerInit() {
if (kbInit) {
return;
// Turn Off
}
document.addEventListener('keyup', keyboardNextPrev, false);
kbInit = true;
}
// Keyboard arrows
function keyboardNextPrev(event) {
if (!kbInit) {
return;
}
switch (event.keyCode) {
case 37: // Left arrow
prevModalArticle();
break;
case 38: // Up arrow
prevModalArticle();
break;
case 39: // Right arrow
nextModalArticle();
break;
case 40: // Down arrow
nextModalArticle();
break;
}
}
// Modal initializer
function modalInit() {
const modalNextButton = document.querySelector('.c-modal-next');
const modalPrevButton = document.querySelector('.c-modal-prev');
modalNextButton.removeEventListener('click', nextModalArticle, false);
modalPrevButton.removeEventListener('click', prevModalArticle, false);
modalNextButton.addEventListener('click', nextModalArticle, false);
modalPrevButton.addEventListener('click', prevModalArticle, false);
keyboardListenerInit();
}
// Retrieve modal index number
function getCurrentModalIndex() {
const modalContent = document.querySelector(
'.mzp-u-modal-content.mzp-c-modal-overlay-contents'
);
const newArticleIndex = parseInt(
modalContent.getAttribute('data-current-index'),
10
);
return newArticleIndex;
}
function updateModalArticle(index) {
const modalContent = document.querySelector(
'.mzp-u-modal-content.mzp-c-modal-overlay-contents'
);
const newArticleId = articleArray[index].getAttribute('data-modal-id');
const newModalContent = document
.querySelector(`[data-modal-parent="${newArticleId}"]`)
.cloneNode(true);
const currentModalContent = modalContent.firstElementChild;
window.location.hash = newArticleId;
modalContent.replaceChild(newModalContent, currentModalContent);
modalContent.setAttribute('data-current-index', index);
modalInit();
}
function nextModalArticle() {
let newArticleIndex = getCurrentModalIndex();
newArticleIndex++;
// If at the end of the gallery, start over
if (newArticleIndex === articleArray.length) {
newArticleIndex = 0;
}
updateModalArticle(newArticleIndex);
}
function prevModalArticle() {
let newArticleIndex = getCurrentModalIndex();
newArticleIndex--;
// If at the beginning of the gallery, start over
if (newArticleIndex < 0) {
newArticleIndex = articleArray.length - 1;
}
updateModalArticle(newArticleIndex);
}
// Iterate through modals
for (let i = 0; i < modalContainers.length; i++) {
const modalContainer = modalContainers[i];
modalContainer.setAttribute('aria-label', 'open modal');
modalContainer.setAttribute('data-current-index', i);
modalContainer.addEventListener('click', function (e) {
e.preventDefault();
const modalId = this.getAttribute('data-modal-id');
const currentIndex = parseInt(
this.getAttribute('data-current-index'),
10
);
const modalContent = document
.querySelector(`[data-modal-parent="${modalId}"]`)
.cloneNode(true);
window.location.hash = modalId;
modalContent.removeAttribute('id');
modalContent.setAttribute('role', 'article');
window.MzpModal.createModal(e.target, content, {
allowScroll: false,
closeText: window.Mozilla.Utils.trans('global-close'),
onCreate: function () {
const contentParent = content.parentElement;
contentParent.classList.add(
'c-careers-full-testimonial-wrapper',
'mzp-l-content',
'mzp-t-content-lg'
);
// removes video modal content that is loading because of similar modal classnames
const video = content.querySelector('.mzp-c-video');
if (video) {
content.removeChild(video);
}
content.appendChild(modalContent);
content.setAttribute('data-current-index', currentIndex);
const modalCloseButton =
document.querySelector('.mzp-c-modal-close');
modalCloseButton.insertAdjacentHTML(
'beforebegin',
modalNextButtonFragment
);
modalCloseButton.insertAdjacentHTML(
'beforebegin',
modalPrevButtonFragment
);
// set next/prev listeners
modalInit();
},
onDestroy: function () {
if (window.history) {
window.history.replaceState(
'',
'',
window.location.pathname
);
}
kbInit = false;
// Re-cache the current modal content which may have changed via next/prev buttons
const modalParent = document.querySelector(
'.mzp-u-modal-content.mzp-c-modal-overlay-contents'
);
const currentModalContent = modalParent.firstElementChild;
modalParent.removeChild(currentModalContent);
}
});
});
}
// trigger modal on page load if hash is present and matches a person with a bio
if (window.location.hash) {
const target = document.getElementById(window.location.hash.substr(1));
if (target && target.classList.contains('has-modal')) {
target.click();
}
}