132 lines
3.5 KiB
JavaScript
132 lines
3.5 KiB
JavaScript
jQuery( function ( $ ) {
|
|
const $modals = $( '.wcs-modal' );
|
|
let $currentModal;
|
|
let $triggerElement;
|
|
|
|
// Resize all open modals on window resize.
|
|
$( window ).on( 'resize', resizeModals );
|
|
|
|
// Initialize modals
|
|
$( $modals ).each( function () {
|
|
trigger = $( this ).data( 'modal-trigger' );
|
|
$( trigger ).on( 'click', { modal: this }, show_modal );
|
|
} );
|
|
|
|
/**
|
|
* Displays the modal linked to a click event.
|
|
*
|
|
* Attaches all close callbacks and resizes to fit.
|
|
*
|
|
* @param {JQuery event} event
|
|
*/
|
|
function show_modal( event ) {
|
|
$triggerElement = $( event.target );
|
|
$currentModal = $( event.data.modal );
|
|
|
|
if ( ! should_show_modal( $currentModal ) ) {
|
|
return;
|
|
}
|
|
|
|
// Prevent the trigger element event being triggered.
|
|
event.preventDefault();
|
|
|
|
const $contentWrapper = $currentModal.find( '.content-wrapper' );
|
|
const $close = $currentModal.find( '.close' );
|
|
|
|
$currentModal.addClass( 'open' );
|
|
resizeModal( $currentModal );
|
|
|
|
$( document.body ).toggleClass( 'wcs-modal-open', true );
|
|
$currentModal.focus();
|
|
document.addEventListener( 'focusin', keepFocusInModal );
|
|
|
|
// Attach callbacks to handle closing the modal.
|
|
$close.on( 'click', () => close_modal( $currentModal ) );
|
|
$currentModal.on( 'click', () => close_modal( $currentModal ) );
|
|
$contentWrapper.on( 'click', ( e ) => e.stopPropagation() );
|
|
|
|
// Close the modal if the escape key is pressed.
|
|
$currentModal.on( 'keyup', function ( e ) {
|
|
if ( 27 === e.keyCode ) {
|
|
close_modal( $currentModal );
|
|
}
|
|
} );
|
|
}
|
|
|
|
/**
|
|
* Closes a modal and resets any forced height styles.
|
|
*
|
|
* @param {JQuery Object} $modal
|
|
*/
|
|
function close_modal( $modal ) {
|
|
$modal.removeClass( 'open' );
|
|
$( $modal ).find( '.content-wrapper' ).css( 'height', '' );
|
|
|
|
if ( 0 === $modals.filter( '.open' ).length ) {
|
|
$( document.body ).removeClass( 'wcs-modal-open' );
|
|
$currentModal = false;
|
|
document.removeEventListener( 'focusin', keepFocusInModal );
|
|
$triggerElement.focus();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Determines if a modal should be displayed.
|
|
*
|
|
* A custom trigger is called to allow third-parties to filter whether the modal should be displayed or not.
|
|
*
|
|
* @param {JQuery Object} modal
|
|
*/
|
|
function should_show_modal( modal ) {
|
|
// Allow third-parties to filter whether the modal should be displayed.
|
|
var event = jQuery.Event( 'wcs_show_modal' );
|
|
event.modal = modal;
|
|
|
|
$( document ).trigger( event );
|
|
|
|
// Fallback to true (show modal) if the result is undefined.
|
|
return undefined === event.result ? true : event.result;
|
|
}
|
|
|
|
/**
|
|
* Resize all open modals to fit the display.
|
|
*/
|
|
function resizeModals() {
|
|
$( $modals ).each( function () {
|
|
if ( ! $( this ).hasClass( 'open' ) ) {
|
|
return;
|
|
}
|
|
|
|
resizeModal( this );
|
|
} );
|
|
}
|
|
|
|
/**
|
|
* Resize a modal to fit the display.
|
|
*
|
|
* @param {JQuery Object} $modal
|
|
*/
|
|
function resizeModal( $modal ) {
|
|
const $modal_container = $( $modal ).find( '.content-wrapper' );
|
|
|
|
// On smaller displays the height is already forced to be 100% in CSS. We just clear any height we might set previously.
|
|
if ( $( window ).width() <= 414 ) {
|
|
$modal_container.css( 'height', '' );
|
|
} else if ( $modal_container.height() > $( window ).height() ) {
|
|
// Force the container height to trigger scroll etc if it doesn't fit on the screen.
|
|
$modal_container.css( 'height', '90%' );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* If focus moves out of the open modal, return focus to it.
|
|
*
|
|
* @param event
|
|
*/
|
|
function keepFocusInModal( event ) {
|
|
if ( $currentModal && ! $currentModal[0].contains( event.target ) ) {
|
|
$currentModal.focus();
|
|
}
|
|
}
|
|
} );
|