(function ($, ally, drupalSettings, window) {
var modalState = {};
modalState.cache = {};
modalState.disabledHandler = null;
modalState.activeElement = null;
modalState.$triggerEl = null;
modalState.video = {
count: 0,
currentVideo: null
};
var fullscreenElement = null;
// Initialize them modal!!
initModals();
// Custom event to reinitialize the modals on the page.
$(window).on('meltmodal:reset', initModals);
// Handle links that require functionality of a
ally.when.key({
context: $('a[data-izimodal-open]'),
enter: simulateButtonClick,
space: simulateButtonClick
});
// Handle when users click on modal triggers
$(document).on('click', '[data-izimodal-open]', function handleModalTriggerClick(evt) {
modalState.$triggerEl = $(evt.currentTarget);
});
// Handle Firefox issue when in fullscreen mode and pressing the "ESC" key,
// the video collapses and doesn't retain the original size.
document.addEventListener('fullscreenchange', function (evt) {
if(document.fullscreenElement){
fullscreenElement = document.fullscreenElement;
}
if (!document.fullscreenElement && document.querySelector('.mejs__container-fullscreen')) {
setTimeout(function () {
var fullscreenBtn = fullscreenElement.querySelector('.mejs__fullscreen-button button');
if (fullscreenBtn) {
fullscreenBtn.click();
fullscreenElement = null;
}
}, 0);
}
});
/***************************************************************************
* Function Declarations
***************************************************************************/
/**
* Main function to initialize the modals.
*/
function initModals() {
// Exit if there are no modal triggers on the page
if (!document.querySelector('[data-izimodal-open]')) { return; }
// Create unique ID's to video modals before instantiating them.
if ($('[data-izimodal-video]').length) {
$('[data-izimodal-video]').each(function () {
var wrapper = $(this).closest('.video-modal-wrapper');
var id = 'video-modal-' + modalState.video.count++;
$('[data-izimodal-video]', wrapper).attr('data-izimodal-open', '#' + id);
$('.video-modal', wrapper).attr('id', id);
});
}
// Initiatialize each modal based on their trigger.
$('[data-izimodal-open]').each(function () {
var target = $(this).attr('data-izimodal-open');
// Exit if the target doesn't exist or has already been initialized
if (!$(target).length || modalState.cache[target]) { return; }
// Store target in modal cache
modalState.cache[target] = true;
var options = {
bodyOverflow: true,
onOpening: onOpening,
onOpened: onOpened,
onClosing: onClosing,
onClosed: onClosed
};
// Allow users to modify options before initializing the modal.
$(window).trigger('meltmodal:options', { options: options, modalState: modalState });
// Initialize modal
$(target).iziModal(options);
});
}
/**
* allyjs event handler for `ally.when.key` to
* simulate functionality for links
*
* @param {object} evt - event object
*/
function simulateButtonClick(evt) {
var target = evt.target;
// Target only anchor tags that have the `data-izimodal-open` attribute.
if (target.nodeName === 'A' && target.hasAttribute('data-izimodal-open')) {
modalState.$triggerEl = $(evt.currentTarget);
evt.preventDefault();
evt.stopImmediatePropagation();
target.click();
}
}
/**
* Handler for `iziModal.options.onOpening` callback
*
* @param {object} modal
*/
function onOpening(modal) {
$(window).trigger('meltmodal:opening', { modalState: modalState });
// Save focus point
modalState.activeElement = document.activeElement;
// Disable all focusable elements exept
// those in the target element.
modalState.disabledHandler = ally.maintain.disabled({
filter: modal.$element
});
// Add url to the continue button of the if the external link modal
if (modalState.$triggerEl.attr('data-externallink-continue')) {
var link = modalState.$triggerEl.attr('href');
var continueLink = modalState.$triggerEl.attr('data-externallink-continue');
$(continueLink, modal.$element).attr('href', link);
$(continueLink, modal.$element).off('click', closeModal);
$(continueLink, modal.$element).on('click', closeModal);
}
handleVideoOptions(modal);
function closeModal() {
modal.close();
}
}
/**
* Handler for `iziModal.options.onOpened` callback
*
* @param {object} modal
*/
function onOpened(modal) {
$(window).trigger('meltmodal:opened', { modalState: modalState });
}
/**
* Handler for `iziModal.optionsonClosed` callback
*
* @param {object} modal
*/
function onClosed() {
$(window).trigger('meltmodal:closed', { modalState: modalState });
// Focus on previously focused element
modalState.activeElement.focus();
}
/**
* Handler for `iziModal.options.onClosing` callback
*
* @param {object} modal
*/
function onClosing(modal) {
$(window).trigger('meltmodal:closing', { modalState: modalState });
if (modalState.video.currentVideo) {
modalState.video.currentVideo.player.pause();
modalState.video.currentVideo.player.load();
}
// Re-enable focusable elements.
modalState.disabledHandler.disengage();
}
/**
* Parses the JSON passed to the `data-izimodal-video` attribute.
* The parsed data is then used to handle functionality of
* `MediaElement.js` video player.
*
*
*
* Autoplay is currently the only option available.
*
* @example
* Open Modal
*
* @param {object} modal - iziModal instance
*/
function handleVideoOptions(modal) {
// Fix for DX8 v5.5.0
if (Drupal.behaviors.DX8MediaElement) {
// Need to set the modal to display block because of the
// CSS selector the `init.mediaelement.js` file that DX8
// uses in the `attach` method won't find the modal:
// ".coh-video > .coh-video-inner:not(".mejs__container"):visible"
modal.$element.css({ display: 'block', opacity: 0 });
// Need to run DX8MediaElement behavior so we can create a
// MediaElementJS instance of the video.
Drupal.behaviors.DX8MediaElement.attach(modal.$element);
// Reset the modal back to it's original state before
// creating the MediaElementJS instance above.
modal.$element.css({ display: 'none', opacity: 1 });
}
// Handle options passed to `data-izimodal-video`
if (modalState.$triggerEl.attr('data-izimodal-video')) {
try {
var data = modalState.$triggerEl.attr('data-izimodal-video');
var options = JSON.parse(data);
var currentVideo = $('video', modal.$element)[0];
var player = currentVideo.player; // mediaelementjs instance
// Store `currentVideo` on modalState so we can use it in other methods
modalState.video.currentVideo = currentVideo;
// Need to reset the video player size so the poster
// image resizes correctly. It appears that setting
// the height doesn't matter so we just set it to `0`.
// We wrap it in a setTimeout so it resizes after the
// modal is finished opening.
setTimeout(function () {
player.setPlayerSize(modal.options.width, 0);
}, 0)
if (options.autoplay) {
player.play();
}
} catch (err) {
console.log(err);
}
}
}
})(jQuery, ally, drupalSettings, window);