/* globals tribe, jQuery */ /** * Makes sure we have all the required levels on the Tribe Object * * @since 4.9.2 * * @type {Object} */ tribe.events = tribe.events || {}; tribe.events.views = tribe.events.views || {}; /** * Configures Views Object in the Global Tribe variable * * @since 4.9.2 * * @type {Object} */ tribe.events.views.manager = {}; /** * Initializes in a Strict env the code that manages the Event Views * * @since 4.9.2 * * @param {Object} $ jQuery * @param {Object} _ Underscore.js * @param {Object} obj tribe.events.views.manager * * @return {void} */ ( function( $, _, obj ) { 'use strict'; var $window = $( window ); /** * Selectors used for configuration and setup * * @since 4.9.2 * * @type {Object} */ obj.selectors = { container: '[data-js="tribe-events-view"]', form: '[data-js="tribe-events-view-form"]', link: '[data-js="tribe-events-view-link"]', dataScript: '[data-js="tribe-events-view-data"]', loader: '.tribe-events-view-loader', loaderText: '.tribe-events-view-loader__text', hiddenElement: '.tribe-common-a11y-hidden', }; /** * Object with the details of the last location URL. * * @since 5.7.0 * * @type {{origin: string, pathname: string}} */ obj.lastLocation = { origin: '', pathname: '', }; /** * Flag when a popstate change is happening. * * @since 4.9.12 * * @type {boolean} */ obj.doingPopstate = false; /** * Stores the current ajax request been handled by the manager. * * @since 4.9.12 * * @type {jqXHR|null} */ obj.currentAjaxRequest = null; /** * Stores the last container that used PushState, which prevents fails. * * @todo @bordoni @paul once shortcodes start managing URLs this will need * to improve to a full tracker of history. * * @since 4.9.12 * * @type {jQuery} */ obj.$lastContainer = $(); /** * Containers on the current page that were initialized. * * @since 4.9.2 * * @type {jQuery} */ obj.$containers = $(); /** * Clean up the container and event listeners * * @since 5.0.0 * * @param {jQuery} container Which element we are going to clean up * * @return {void} */ obj.cleanup = function( container ) { var $container = $( container ); var $form = $container.find( obj.selectors.form ); var $data = $container.find( obj.selectors.dataScript ); var data = {}; // If we have data element set it up. if ( $data.length ) { data = JSON.parse( $data.text().trim() ); } $container.trigger( 'beforeCleanup.tribeEvents', [ $container, data ] ); $container.find( obj.selectors.link ).off( 'click.tribeEvents', obj.onLinkClick ); if ( $form.length ) { $form.off( 'submit.tribeEvents', obj.onSubmit ); } $container.trigger( 'afterCleanup.tribeEvents', [ $container, data ] ); }; /** * Setup the container for views management * * @since 4.9.2 * * @todo Requirement to setup other JS modules after hijacking Click and Submit * * @param {Integer} index jQuery.each index param * @param {Element|jQuery} container Which element we are going to setup * * @return {void} */ obj.setup = function( index, container ) { var $container = $( container ); var $form = $container.find( obj.selectors.form ); var $data = $container.find( obj.selectors.dataScript ); var data = {}; // If we have data element set it up. if ( $data.length ) { data = JSON.parse( $data.text().trim() ); } $container.trigger( 'beforeSetup.tribeEvents', [ index, $container, data ] ); $container.find( obj.selectors.link ).on( 'click.tribeEvents', obj.onLinkClick ); // Only catch the submit if properly setup on a form if ( $form.length ) { $form.on( 'submit.tribeEvents', obj.onSubmit ); } $container.trigger( 'afterSetup.tribeEvents', [ index, $container, data ] ); }; /** * Given an Element determines it's view container * * @since 4.9.2 * * @param {Element|jQuery} element Which element we getting the container from * * @return {jQuery} */ obj.getContainer = function( element ) { var $element = $( element ); if ( ! $element.is( obj.selectors.container ) ) { return $element.parents( obj.selectors.container ).eq( 0 ); } return $element; }; /** * Given an Element determines it's view container data from the script. * * @since 4.9.2 * * @param {jQuery} $container Which element we getting the data from. * * @return {mixed} */ obj.getContainerData = function( $container ) { var $data = $container.find( obj.selectors.dataScript ); // Bail in case we dont find data script. if ( ! $data.length ) { return; } var data = JSON.parse( $data.text().trim() ); return data; }; /** * Given an container determines if it should manage URL. * * @since 4.9.4 * * @param {Element|jQuery} $container Which element we are using as the container. * * @return {Boolean} */ obj.shouldManageUrl = function( $container ) { var shouldManageUrl = $container.data( 'view-manage-url' ); var tribeIsTruthy = /^(true|1|on|yes)$/; // When undefined we use true as the default. if ( typeof shouldManageUrl === typeof undefined ) { shouldManageUrl = true; } else { // When not undefined we cast as string and test for valid boolean truth. shouldManageUrl = tribeIsTruthy.test( String( shouldManageUrl ) ); } return shouldManageUrl; }; /** * Using data passed by the Backend once we fetch a new HTML via an * container action. * * Usage, on the AJAX request we will pass data back using a