/**
* 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() {
// Nothing is built here on purpose. The modal markup (and its
// empty
) used to be injected
// into as soon as this script loaded — on every page,
// including ones with no 360° tour. It is now created on the
// first view() call, so pages that never open a tour never get
// the extra DOM.
}
/**
* Build the modal once, on first use.
*/
ensureModal() {
if (this.modal) {
return;
}
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;
this.ensureModal();
// 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() {
if (!this.modal) {
return; // never opened on this page
}
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() {
if (!this.modal) {
return;
}
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
})();