/** * Yatra 360° Tour Viewer Module * Reusable 360° virtual tour viewer * * @package Yatra * @version 1.0.0 */ (function() { 'use strict'; // Translation helper. Resolves through wp.i18n.__() when wp-i18n is // enqueued (FrontendAssetsProvider registers it as a dependency for // this script); falls back to identity so the page never breaks // when the i18n runtime is unavailable on older builds. // // IMPORTANT — call sites MUST pass `'yatra'` as the second arg even // though the shim ignores it. `wp i18n make-pot --domain=yatra` // filters extraction to calls whose LITERAL second argument is the // domain, so a bare `__('x')` is silently dropped from the .pot. var __ = (window.wp && window.wp.i18n && window.wp.i18n.__) ? function (text, domain) { return window.wp.i18n.__(text, domain || 'yatra'); } : function (text) { return text; }; class YatraTourViewer { constructor() { this.modal = null; this.iframe = null; this.currentTour = null; this.init(); } init() { this.createModal(); this.attachEventListeners(); } createModal() { // Check if modal already exists if (document.getElementById('yatra-tour-viewer-modal')) { this.modal = document.getElementById('yatra-tour-viewer-modal'); this.iframe = document.getElementById('yatra-tour-viewer-iframe'); return; } // Pre-compute translated labels OUT of the template literal so // makepot extracts them reliably. `wp i18n make-pot` doesn't // always traverse into `${ }` interpolations; calls at top- // level statements are always picked up. var closeTourLabel = __('Close Tour', 'yatra'); var fullscreenLabel = __('Fullscreen', 'yatra'); // Create modal HTML const modalHTML = ` `; // Append to body document.body.insertAdjacentHTML('beforeend', modalHTML); this.modal = document.getElementById('yatra-tour-viewer-modal'); this.iframe = document.getElementById('yatra-tour-viewer-iframe'); } attachEventListeners() { // Close button const closeBtn = this.modal.querySelector('.yatra-tour-viewer-close'); if (closeBtn) { closeBtn.addEventListener('click', () => this.close()); } // Overlay click to close const overlay = this.modal.querySelector('.yatra-tour-viewer-overlay'); if (overlay) { overlay.addEventListener('click', () => this.close()); } // Fullscreen button const fullscreenBtn = this.modal.querySelector('.yatra-tour-viewer-fullscreen'); if (fullscreenBtn) { fullscreenBtn.addEventListener('click', () => this.toggleFullscreen()); } // ESC key to close document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && this.modal.style.display === 'flex') { this.close(); } }); } /** * View a 360° tour * @param {Object} tour - Tour object with url, title, tour_type */ view(tour) { if (!tour || !tour.url) { console.error('YatraTourViewer: Invalid tour object'); return; } this.currentTour = tour; // Set title const titleElement = this.modal.querySelector('.yatra-tour-viewer-title'); if (titleElement) { titleElement.textContent = tour.title || __('360° Virtual Tour', 'yatra'); } // Set iframe source this.iframe.src = tour.url; // Show modal this.open(); } open() { this.modal.style.display = 'flex'; document.body.style.overflow = 'hidden'; } close() { this.modal.style.display = 'none'; document.body.style.overflow = ''; // Stop tour by clearing iframe src this.iframe.src = ''; this.currentTour = null; // Exit fullscreen if active if (document.fullscreenElement) { document.exitFullscreen(); } } toggleFullscreen() { const wrapper = this.modal.querySelector('.yatra-tour-viewer-wrapper'); if (!document.fullscreenElement) { if (wrapper.requestFullscreen) { wrapper.requestFullscreen(); } else if (wrapper.webkitRequestFullscreen) { wrapper.webkitRequestFullscreen(); } else if (wrapper.msRequestFullscreen) { wrapper.msRequestFullscreen(); } } else { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } } } } // Create global instance window.YatraTourViewer = new YatraTourViewer(); // Log successful initialization })();