Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
drupal/melt_modal / js / meltModal.js
Size: Mime:
(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 <button />
    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 <button /> 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
     * <a href="#" data-izimodal-video='{"autoplay": true}' data-izimodal-open>Open Modal</a>
     *
     * @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);