PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 9.1.3
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v9.1.3
9.1.3 9.1.2 9.1.1 9.1.0 9.0.3 9.0.2 9.0.1 9.0.0 8.5.79 8.5.78 8.5.77 8.5.76 8.5.75 8.5.74 8.5.73 8.5.72 8.5.71 8.5.70 8.5.69 8.5.68 8.5.35 8.5.36 8.5.37 8.5.38 8.5.39 All 222 releases
wpvr / legacy / admin / js / wpvr-admin.js

wpvr-admin.js in WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress 9.1.3, at legacy/admin/js/wpvr-admin.js

3,769 lines 170.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function ($) {
2 'use strict';
3 var j = 1;
4 var color = '#00b4ff';
5 var scene_parent = '';
6 var scene_uploader = null;
7 var scene_upload_parent = null;
8
9 window.jQuery.migrateMute = true;
10 /**
11 * All of the code for your admin-facing JavaScript source
12 * should reside in this file.
13 *
14 * Note: It has been assumed you will write jQuery code here, so the
15 * $ function reference has been prepared for usage within the scope
16 * of this function.
17 *
18 * This enables you to define handlers, for when the DOM is ready:
19 *
20 * $(function() {
21 *
22 * });
23 *
24 * When the window is loaded:
25 *
26 * $( window ).load(function() {
27 *
28 * });
29 *
30 * ...and/or other possibilities.
31 *
32 * Ideally, it is not considered best practise to attach more than a
33 * single DOM-ready or window-load handler for a particular page.
34 * Although scripts in the WordPress core, Plugins and Themes may be
35 * practising this, we should strive to set a better example in our own work.
36 */
37
38 let lastChildClicked = false;
39 $(document).ready(function () {
40 if($('#scene-1').find('input.sceneid').val()){
41 $('.scene-gallery').append('<ul style="width:150px;"><li class="owlscene owl" ></li><li title="Double click to Upload scene"><div class="upload-scene-wrapper"><img loading="lazy" class="scctrl upload-form-scene-gallery" src="'+window.wpvr_localize.WPVR_ASSET_PATH+'/icon/scene-upload.svg"><p>Upload Scene</p></div></li></ul>');
42 }else{
43 $('.scene-gallery').append('<ul style="width:150px;"><li class="owlscene owl" ></li><li title="Double click to Upload scene"><div class="upload-scene-wrapper-first"><img loading="lazy" class="scctrl upload-form-scene-gallery-first" src="'+window.wpvr_localize.WPVR_ASSET_PATH+'/icon/scene-upload.svg"><p>Upload Scene</p></div></li></ul>');
44 }
45
46 $(".vrowl-carousel").owlCarousel({
47 margin: 10,
48 autoWidth: true,
49 nav: true
50 });
51
52 var primary_markng = $('#scene-1').find('input.sceneid').val();
53 $('.owl' + primary_markng).parents('.owl-item').addClass('marked');
54
55 $('.meta-box-sortables').sortable({
56 items: '#wpvr_item_builder_box',
57 disabled: true
58 });
59
60 $('.postbox .hndle').css('cursor', 'pointer');
61
62 // Validate scene checkbox on page load
63 setTimeout(function() {
64 let sceneImageCount = $('.rex-pano-tab .single-scene .scene-left .scene-setting .form-group img')
65 .filter(function() {
66 return $(this).attr('src') && $(this).attr('src').trim() !== '';
67 })
68 .length;
69
70 var panovideo = $("input[name='panovideo']:checked").val();
71 var videourl = $("input[name='video-attachment-url']").val();
72 var hasContent = (panovideo === 'on' && videourl && videourl.trim() !== '') || sceneImageCount > 0;
73
74 if (sceneImageCount === 0) {
75 $('#wpvr-check-scene').prop('checked', false);
76 $('#wpvr-check-media').prop('checked', false);
77 $('#wpvr-check-scene').closest('.wpvr-checklist-item').css('color', '#73707D');
78 $('#wpvr-check-media').closest('.wpvr-checklist-item').css('color', '#73707D');
79 updateProgress();
80 }
81
82 // Hide Panellum loading box if no content
83 if (!hasContent) {
84 $('.pnlm-load-box').hide();
85 }
86 }, 100);
87
88
89 });
90
91 $(document).on("change", "input.vr-switcher-check", function (event) {
92 updateCheckboxStates();
93 $(this).val(this.checked ? 'on' : 'off');
94 });
95
96 updateCheckboxStates();
97 function updateCheckboxStates() {
98 // Check movement controls if wpvr_controls is checked
99 if ($('#wpvr_controls').prop('checked')) {
100 $('#wpvr-check-movement-controls').prop('checked', true);
101 $('#wpvr-check-movement-controls').closest('.wpvr-checklist-item').css('color', '#0E003C');
102 } else if (!$('#wpvr_controls').prop('checked')) {
103 $('#wpvr-check-movement-controls').prop('checked', false);
104 $('#wpvr-check-movement-controls').closest('.wpvr-checklist-item').css('color', '#73707D');
105 }
106
107 // Check zoom controls if either wpvr_mouseZoom or wpvr_keyboardzoom is checked
108 if (($('#wpvr_mouseZoom').prop('checked') || $('#wpvr_keyboardzoom').prop('checked'))) {
109 $('#wpvr-check-zoom-controls').prop('checked', true);
110 $('#wpvr-check-zoom-controls').closest('.wpvr-checklist-item').css('color', '#0E003C');
111 } else if (!$('#wpvr_mouseZoom').prop('checked') && !$('#wpvr_keyboardzoom').prop('checked')) {
112 $('#wpvr-check-zoom-controls').prop('checked', false);
113 $('#wpvr-check-zoom-controls').closest('.wpvr-checklist-item').css('color', '#73707D');
114 }
115
116 updateProgress();
117 }
118
119
120 // === Pro Preview: Sticky Banner & Watermark for Free Users on Advanced Controls ===
121 (function initProPreview() {
122 if (typeof wpvr_obj === 'undefined' || wpvr_obj.is_wpvr_pro_active) {
123 return;
124 }
125
126 var $banner = $('#wpvr-pro-preview-banner');
127 var $watermark = $('#wpvr-pro-preview-watermark');
128
129 // All toggleable IDs in the Advanced Controls tab
130 var advancedControlIds = [
131 'wpvr_diskeyboard', 'wpvr_keyboardzoom', 'wpvr_draggable',
132 'wpvr_mouseZoom', 'wpvr_gyro', 'wpvr_deviceorientationcontrol', 'wpvr_compass',
133 'wpvr_vrgallery', 'wpvr_vrgallery_title', 'wpvr_scene_navigation',
134 'wpvr_bg_music', 'wpvr_explainerSwitch', 'wpvr_globalzoom', 'wpvr_cpLogoSwitch'
135 ];
136
137 // Option A: IDs whose effect is visible via pannellum config (auto-trigger preview)
138 var pannellumConfigIds = [
139 'wpvr_compass', 'wpvr_diskeyboard', 'wpvr_keyboardzoom',
140 'wpvr_draggable', 'wpvr_mouseZoom'
141 ];
142
143 // Option B: IDs mapped to their mockup overlay elements
144 var mockupMap = {
145 'wpvr_vrgallery': '#wpvr-pro-mockup-gallery',
146 'wpvr_scene_navigation': '#wpvr-pro-mockup-navigation',
147 'wpvr_bg_music': '#wpvr-pro-mockup-audio',
148 'wpvr_gyro': '#wpvr-pro-mockup-gyro'
149 };
150
151 var previewDebounceTimer = null;
152
153 // Enable the disabled checkboxes in the advanced controls tab for Pro Preview
154 function enableAdvancedToggles() {
155 $('#gen-advanced input.vr-switcher-check[disabled]').each(function () {
156 $(this).prop('disabled', false).addClass('wpvr-pro-preview-toggle');
157 });
158 }
159
160 function hasAnyAdvancedToggleOn() {
161 for (var i = 0; i < advancedControlIds.length; i++) {
162 var $el = $('#' + advancedControlIds[i]);
163 if ($el.length && $el.prop('checked')) {
164 return true;
165 }
166 }
167 return false;
168 }
169
170 function updateProPreviewState() {
171 if (hasAnyAdvancedToggleOn()) {
172 $banner.slideDown(200);
173 $watermark.fadeIn(200);
174 } else {
175 $banner.slideUp(200);
176 $watermark.fadeOut(200);
177 }
178 }
179
180 // Option B: Show/hide CSS mockup overlays based on toggle state
181 function updateMockups() {
182 $.each(mockupMap, function (toggleId, mockupSelector) {
183 var $checkbox = $('#' + toggleId);
184 var $mockup = $(mockupSelector);
185 if ($checkbox.length && $checkbox.prop('checked')) {
186 $mockup.fadeIn(200);
187 } else {
188 $mockup.fadeOut(200);
189 }
190 });
191
192 // Adjust audio mockup position when gallery is also visible
193 var galleryOn = $('#wpvr_vrgallery').prop('checked');
194 var $audio = $('#wpvr-pro-mockup-audio');
195 if (galleryOn) {
196 $audio.addClass('wpvr-pro-mockup--has-gallery');
197 } else {
198 $audio.removeClass('wpvr-pro-mockup--has-gallery');
199 }
200 }
201
202 // Option A: Auto-trigger preview for features that work via pannellum config
203 function autoTriggerPreview(toggleId) {
204 if (pannellumConfigIds.indexOf(toggleId) === -1) {
205 return;
206 }
207 // Only auto-preview if a scene image exists
208 var hasScene = $('#scene-1').find('input.sceneid').val();
209 if (!hasScene) {
210 return;
211 }
212 clearTimeout(previewDebounceTimer);
213 previewDebounceTimer = setTimeout(function () {
214 $('.panolenspreview').trigger('click');
215 }, 600);
216 }
217
218 // Listen for toggle changes on advanced control checkboxes
219 $(document).on('change', '#gen-advanced input.vr-switcher-check', function () {
220 updateProPreviewState();
221 updateMockups();
222 autoTriggerPreview($(this).attr('id'));
223 });
224
225 // Update state when the Advanced Controls tab is shown
226 $(document).on('click', '.inner-nav li.gen-advanced', function () {
227 setTimeout(function () {
228 enableAdvancedToggles();
229 updateProPreviewState();
230 updateMockups();
231 }, 100);
232 });
233
234 // Initial check when DOM is ready
235 $(document).ready(function () {
236 enableAdvancedToggles();
237 if ($('#gen-advanced').is(':visible')) {
238 updateProPreviewState();
239 updateMockups();
240 }
241 });
242 })();
243 // === End Pro Preview ===
244
245
246 var specificeSceneID = ''
247 var newScene = ''
248 $(document).on("click", ".scene-nav ul li span", function (event) {
249 var clickedSceneTab = this;
250 $('.owl-item').removeClass('marked');
251 setTimeout(function(){
252 var target = $('.scene-nav ul li.active span').attr("data-index");
253 if(target == undefined){
254 var currentLi = $(clickedSceneTab).parent('li');
255 var previousLi = currentLi.prev();
256 if (previousLi.length > 0) {
257 newScene = previousLi.find('span').attr('data-index');
258 }
259 }
260 var data = $('#scene-' + target).find('input.sceneid').val();
261 if (data) {
262 specificeSceneID = data;
263 if(!lastChildClicked){
264 $('.panolenspreview').trigger('click')
265 }
266 $('.owl' + data).parents('.owl-item').addClass('marked');
267 }
268 lastChildClicked = false;
269 }, 500);
270 });
271
272 jQuery(document).ready(function ($) {
273
274 j = $('#scene-1').find('.hotspot-nav li').eq(-2).find('span').attr('data-index');
275 var ajaxurl = wpvr_obj.ajaxurl;
276 $('.panolenspreview').on('click', function (e) {
277 e.preventDefault();
278 $('.wpvr-loading').show();
279 var videourl = $("input[name='video-attachment-url']").val();
280 var autoplay = $("input[name='autoplay']:checked").val();
281 var loop = $("input[name='loop']:checked").val();
282
283 var panovideo = $("input[name='panovideo']:checked").val();
284
285 var postid = $("#post_ID").val();
286 var autoload = $("input[name='autoload']").is(':checked') ? 'on' : 'off';
287 var compass = $("input[name='compass']:checked").val();
288 var control = $("input[name='controls']").is(':checked') ? 'on' : 'off';
289 var rotation = $("input[name='autorotation']").is(':checked') ? 'on' : 'off';
290 var defaultscene = $("input[name='default-scene-id']").val();
291 var preview = $("input[name='preview-attachment-url']").val();
292 var scenefadeduration = $("input[name='scene-fade-duration']").val();
293
294 var autorotation = $("input[name='auto-rotation']").val();
295 var autorotationinactivedelay = $("input[name='auto-rotation-inactive-delay']").val();
296 var autorotationstopdelay = $("input[name='auto-rotation-stop-delay']").val();
297
298 var panodata = $('.scene-setup').repeaterVal();
299 const filteredPanodata = {
300 ...panodata,
301 "scene-list": panodata["scene-list"].filter(
302 scene => scene["scene-id"]?.trim()
303 )
304 };
305 var panolist = JSON.stringify(filteredPanodata);
306 var previewtext = $('.previewtext').val();
307
308 // Collect advanced control values for Pro Preview.
309 // draggable defaults to 'on' — it is a basic feature and must be
310 // enabled in the preview so pannellum can capture hotspot coordinates.
311 var diskeyboard = $('#wpvr_diskeyboard').is(':checked') ? 'on' : 'off';
312 var keyboardzoom = $('#wpvr_keyboardzoom').is(':checked') ? 'on' : 'off';
313 var draggable = 'on'; // always enabled; dragging is required for hotspot coordinate capture
314 var mouseZoom = $('#wpvr_mouseZoom').is(':checked') ? 'on' : 'off';
315 var gyro = $('#wpvr_gyro').is(':checked') ? 'on' : 'off';
316 var deviceorientationcontrol = $('#wpvr_deviceorientationcontrol').is(':checked') ? 'on' : 'off';
317
318 jQuery.ajax({
319 type: "POST",
320 url: ajaxurl,
321 data: {
322 action: "wpvr_preview",
323 nonce : wpvr_obj.ajax_nonce,
324 postid: postid,
325 compass: compass,
326 control: control,
327 autoload: autoload,
328 panodata: panolist,
329 defaultscene: defaultscene,
330 rotation: rotation,
331 autorotation: autorotation,
332 autorotationinactivedelay: autorotationinactivedelay,
333 autorotationstopdelay: autorotationstopdelay,
334 preview: preview,
335 scenefadeduration: scenefadeduration,
336 panovideo: panovideo,
337 videourl: videourl,
338 autoplay: autoplay,
339 loop: loop,
340 // vidautoplay: vidautoplay,
341 // vidcontrol: vidcontrol,
342 diskeyboard: diskeyboard,
343 keyboardzoom: keyboardzoom,
344 draggable: draggable,
345 mouseZoom: mouseZoom,
346 gyro: gyro,
347 deviceorientationcontrol: deviceorientationcontrol
348 },
349
350 success: function (response) {
351 $('.wpvr-loading').hide();
352 if (response.success == true) {
353 if(response.data[2] == 'off'){
354 $('#error_occured').hide();
355 $('#error_occuredpub').hide();
356 $('#' + response.data[0]["panoid"]).empty();
357 var scenes = response.data[1];
358
359 if (scenes) {
360 $.each(scenes.scenes, function (i) {
361 $.each(scenes.scenes[i]['hotSpots'], function (key, val) {
362 if (
363 val["clickHandlerArgs"] &&
364 val["clickHandlerArgs"].replace(/<[^>]*>/g, '').trim() !== ''
365 ) {
366 val["clickHandlerFunc"] = wpvrhotspot;
367 }
368 if (
369 val["createTooltipArgs"] &&
370 val["createTooltipArgs"].replace(/<[^>]*>/g, '').trim() !== ''
371 ) {
372 val["createTooltipFunc"] = wpvrtooltip;
373 }
374 });
375 });
376 }
377 if (scenes) {
378 $('.scene-gallery').trigger('destroy.owl.carousel');
379 $('.scene-gallery').empty();
380
381 $.each(scenes.scenes, function (key, val) {
382 $('.scene-gallery').append('<ul style="width:150px;"><li class="owlscene owl' + key + '">' + key + '</li><li title="Click to view scene"><img loading="lazy" class="scctrl" id="' + key + '_gallery" src="' + val.panorama + '"></li></ul>');
383 });
384 $('.scene-gallery').append('<ul style="width:150px;"><li class="owlscene owl" ></li><li title="Double click to Upload scene"><div class="upload-scene-wrapper"><img loading="lazy" class="scctrl upload-form-scene-gallery" src="'+window.wpvr_localize.WPVR_ASSET_PATH+'/icon/scene-upload.svg"><p>Upload Image</p></div></li></ul>');
385
386 $(".vrowl-carousel").owlCarousel({
387 margin: 10,
388 autoWidth: true,
389 });
390 var active_owl_target = $('#wpvr_active_scenes').val();
391 var get_owl_target = $('#scene-' + active_owl_target).find('input.sceneid').val();
392 $('.owl' + get_owl_target).parents('.owl-item').addClass('marked');
393 }
394
395 if(!scenes.autoLoad){
396 jQuery('.pnlm-controls-container').hide();
397 }
398
399 var panoshow = pannellum.viewer(response.data[0]["panoid"], scenes);
400
401 panoshow.on('load', function(){
402 jQuery('.pnlm-controls-container').show();
403 });
404
405 if (scenes.autoRotate) {
406 panoshow.on('load', function () {
407 setTimeout(function () {
408 panoshow.startAutoRotate(scenes.autoRotate, 0);
409 }, 3000);
410 });
411 panoshow.on('scenechange', function () {
412 setTimeout(function () {
413 panoshow.startAutoRotate(scenes.autoRotate, 0);
414 }, 3000);
415 });
416 }
417 if (scenes) {
418 $.each(scenes.scenes, function (key, val) {
419 document.getElementById('' + key + '_gallery').addEventListener('click', function (e) {
420 $('.owl-item').removeClass('marked');
421 $(this).closest('.owl-item').addClass('marked');
422 if (panoshow.getScene() !== key) {
423 panoshow.loadScene(key);
424 }
425 activateSceneTab(key);
426 });
427 });
428 }
429 if( newScene){
430 var data = $('#scene-' + newScene).find('input.sceneid').val();
431 if(data){
432 panoshow.loadScene(data);
433 }
434 //newScene = ''
435 }
436 if(specificeSceneID){
437 setTimeout(() => {
438 panoshow.loadScene(specificeSceneID);
439 }, 500);
440 }
441 $('html, body').animate({
442 scrollTop: $("#wpvr_item_builder__box").offset().top
443 }, 500);
444 //set preview text
445 if ("" != previewtext) {
446 $('.pnlm-load-button p').text(previewtext);
447 }
448 }else{
449 $('#' + response.data["panoid"]).empty();
450 $('#' + response.data["panoid"]).html(response.data["panodata"]);
451 if (response.data['vidtype'] == 'selfhost') {
452 videojs(response.data["vidid"], {
453 plugins: {
454 pannellum: {}
455 }
456 });
457 }
458 $('html, body').animate({
459 scrollTop: $("#wpvr_item_builder__box").offset().top
460 }, 500);
461 }
462
463 } else {
464 $('#error_occured').show();
465 $('#error_occured .pano-error-message').html(response.data);
466 $('#error_occuredpub').show();
467 $('#error_occuredpub').html(response.data);
468 $('body').addClass('error-overlay');
469 $('html, body').animate({
470 scrollTop: $("#error_occured").offset().top
471 }, 500);
472 }
473
474 }
475 });
476 });
477 });
478
479
480 function sanitizeText(str) {
481 if (!str) return '';
482 // Remove all <script> tags and their content
483 str = str.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
484 // Optional: remove all remaining HTML tags if you want plain text
485 str = str.replace(/<\/?[^>]+(>|$)/g, "");
486 return str;
487 }
488
489
490 function activateSceneTab(sceneId){
491 jQuery(".scene-nav ul li span").each(function() {
492 var sceneTab = jQuery(this);
493 var dataHrefValue = sceneTab.attr("data-href");
494 var scenePanel = jQuery(dataHrefValue);
495 var currentScene = scenePanel.find('input.sceneid').val();
496
497 if(sceneId == currentScene){
498 jQuery([sceneTab.parent()[0], scenePanel[0]])
499 .addClass('active')
500 .siblings('.active')
501 .removeClass('active');
502 jQuery('#wpvr_active_scenes').val(sceneTab.data('index'));
503 return false;
504 }
505 });
506 }
507
508 //-- Set Cookie--//
509
510 function setCookie(cName, cValue, expDays) {
511 let date = new Date();
512 date.setTime(date.getTime() + (expDays * 24 * 60 * 60 * 1000));
513 const expires = "expires=" + date.toUTCString();
514 document.cookie = cName + "=" + cValue + "; " + expires + "; path=/";
515 }
516 // Get a cookie
517
518 function getCookie(cName) {
519 const name = cName + "=";
520 const cDecoded = decodeURIComponent(document.cookie); //to be careful
521 const cArr = cDecoded .split('; ');
522 let res;
523 cArr.forEach(val => {
524 if (val.indexOf(name) === 0) res = val.substring(name.length);
525 })
526 return res;
527 }
528
529 function getParameterByName(name, url = window.location.href) {
530 name = name.replace(/[\[\]]/g, '\\$&');
531 var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
532 results = regex.exec(url);
533 if (!results) return null;
534 if (!results[2]) return '';
535 return decodeURIComponent(results[2].replace(/\+/g, ' '));
536 }
537 function findValueByName(name,dataArray) {
538 for (var i = 0; i < dataArray.length; i++) {
539 if (dataArray[i].name === name) {
540 return dataArray[i].value;
541 }
542 }
543 // Return a default value or handle the case when the name is not found
544 return '';
545 }
546
547 jQuery(document).ready(function ($) {
548 var getRedirectUrl = getCookie("redirectUrl");
549 var getCookiePostID = getCookie("postID");
550
551 const urlParams = getParameterByName("active_tab");
552 const action = wpvr_global_obj.url_info.param.action;
553 let getPostID = wpvr_global_obj.url_info.param.post;
554
555 if(getCookiePostID == getPostID){
556 if(urlParams == '' || urlParams == undefined){
557 if (action == 'edit' && getRedirectUrl != undefined){
558 window.location.replace(getRedirectUrl)
559 setCookie('postID', '', 1);
560 setCookie('redirectUrl', '', 1);
561 }
562 }
563 }
564 var flag_ok = false;
565 $('#publish').on('click', function (e) {
566 e.preventDefault();
567
568 var hidden_post_status = $('#hidden_post_status').val() || 'auto-draft';
569 var action_type = (hidden_post_status === 'publish') ? 'update' : 'publish';
570 $('#publish').prop('disabled', true);
571 $('.panolenspreview').trigger('click')
572 var data = $('form#post').serializeArray();
573 var post_status = findValueByName('post_status',data)
574 var hidden_post_status = findValueByName('hidden_post_status',data)
575 var hidden_post_password = findValueByName('hidden_post_password',data)
576 var hidden_post_visibility = findValueByName('hidden_post_visibility',data)
577 var visibility = findValueByName('visibility',data)
578 var post_password = findValueByName('post_password',data)
579 var post_title = findValueByName('post_title',data)
580 var x = $(this).val();
581 // if (!flag_ok) {
582 $('.wpvr-loading').show();
583 var postid = Number($("#post_ID").val() || 0);
584 var panovideo = $("input[name='panovideo']:checked").val();
585 var videourl = $("input[name='video-attachment-url']").val();
586 var autoload = $("input[name='autoload']").is(':checked') ? 'on' : 'off';
587 var control = $("input[name='controls']").is(':checked') ? 'on' : 'off';
588 var compass = $("input[name='compass']:checked").val();
589 var defaultscene = $("input[name='default-scene-id']").val();
590 var preview = $("input[name='preview-attachment-url']").val();
591 var rotation = $("input[name='autorotation']").is(':checked') ? 'on' : 'off'; // Auto Rotation checkbox value
592 var autorotation = $("input[name='auto-rotation']").val();
593 var autorotationinactivedelay = $("input[name='auto-rotation-inactive-delay']").val();
594 var autorotationstopdelay = $("input[name='auto-rotation-stop-delay']").val();
595
596 var scenefadeduration = $("input[name='scene-fade-duration']").val();
597 var previewtext = $('.previewtext').val();
598 if ($('.scene-setup')[0]) {
599 var panodata = $('.scene-setup').repeaterVal();
600
601 var panolist = JSON.stringify(panodata);
602 } else {
603 var panodata = '';
604 var panolist = '';
605 }
606
607
608 //get the checklist data
609 var checklistData = {};
610 var checklistKeys = [
611 'scene',
612 'media',
613 'default',
614 'hotspots',
615 'movement-controls',
616 'publish'
617 ];
618
619 if(wpvr_obj?.is_wpvr_pro_active){
620 checklistKeys.push('zoom-controls');
621 }
622
623 checklistKeys.forEach(function (key) {
624 checklistData['wpvr_check_' + key] = document.getElementById('wpvr-check-' + key).checked;
625 });
626
627 jQuery.ajax({
628
629 type: "POST",
630 url: ajaxurl,
631 data: {
632 action: "wpvr_save",
633 action_type: action_type,
634 nonce : wpvr_obj.ajax_nonce,
635 postid: postid,
636 panovideo: panovideo,
637 videourl: videourl,
638 control: control,
639 compass: compass,
640 autoload: autoload,
641 panodata: panolist,
642 defaultscene: defaultscene,
643 preview: preview,
644 rotation: rotation, // Auto Rotation checkbox value
645 autorotation: autorotation, // Rotatin speed
646 autorotationinactivedelay: autorotationinactivedelay,
647 autorotationstopdelay: autorotationstopdelay,
648 scenefadeduration: scenefadeduration,
649 previewtext: previewtext,
650
651 hidden_post_status: hidden_post_status,
652 post_status: post_status,
653 hidden_post_password: hidden_post_password,
654 hidden_post_visibility: hidden_post_visibility,
655 visibility: visibility,
656 post_password: post_password,
657 post_value: $('#publish').val(),
658 post_title: post_title,
659 checklistData: checklistData,
660 },
661
662 success: function (response) {
663
664 $('.wpvr-loading').hide();
665 $('#publish').prop('disabled', false);
666 if (response.success == false) {
667 $('#error_occured').show();
668 $('#error_occured .pano-error-message').html(response.data);
669 $('#error_occuredpub').show();
670 $('#error_occuredpub').html(response.data);
671
672 $('body').addClass('error-overlay');
673 $('html, body').animate({
674 scrollTop: $("#error_occured").offset().top
675 }, 500);
676 } else {
677 $('#hidden_post_status').val(response.data.post_status)
678 if(!$('#wpvr-check-publish').prop('checked')){
679 $('#wpvr-check-publish').prop('checked', true);
680 $('#wpvr-check-publish').closest('.wpvr-checklist-item').css('color', '#0E003C');
681 }
682 updateProgress();
683
684 flag_ok = true;
685 $("#publishing-action").prepend(
686 `<div class="success-message" id="wpvr-success-message">
687 <p>${wpvr_obj?.successfully_updated}</p>
688 </div>`
689 );
690 setTimeout(function(){
691 $("#wpvr-success-message").remove();
692 }, 3000 );
693 var url_info = wpvr_global_obj.url_info
694 var oldUrl = '';
695 let params = (new URL(document.location)).searchParams;
696 let active_tab = params.get('active_tab');
697 oldUrl = url_info.admin_url+"post.php?"+"post="+postid+"&action=edit"+"&active_tab="+active_tab;
698 if ( 'add' == url_info.screen ){
699 setCookie('redirectUrl', oldUrl, 1);
700 setCookie('postID', postid, 1);
701 }else{
702 setCookie('postID', postid, 1);
703
704 setCookie('redirectUrl', oldUrl, 1);
705 }
706 var published_label = wpvr_obj?.published_text || 'Published';
707 if ($("#post_status option[value='publish']").length === 0) {
708 $("#post_status").append('<option value="publish">' + published_label + '</option>');
709 }
710
711 if (response.data.post_status === 'publish') {
712 $("#post_status").val('publish');
713 $("#hidden_post_status").val('publish');
714 $("#post-status-display").text(published_label);
715 } else {
716 var statusText = $("#post_status option:selected").text();
717 $("#post-status-display").text(statusText);
718 }
719
720 var status = response.data.post_status;
721 var statusText = 'publish' == status ? 'Published' : $("#post_status").val()
722 $("#post-status-display").text(statusText);
723 let site_language = wpvr_obj?.site_language;
724 let translatedText = wpvr_obj?.translated_languages?.[site_language] ?? {};
725 if(response.data.post_status == 'draft'){
726 let publish_text = translatedText?.['Publish'] ?? 'Publish';
727 $('#publish').val(publish_text);
728 }else{
729 let update_text = translatedText?.['Update'] ?? 'Update';
730 $('#publish').val(update_text);
731 }
732 window.history.replaceState(null, '', url_info.admin_url+"post.php?"+"post="+postid+"&action=edit");
733 resetPostFormDirtyState();
734 }
735 }
736 });
737 // }
738 });
739 });
740
741 function resetPostFormDirtyState() {
742 const $form = $('#post');
743
744 if (!$form.length) {
745 return;
746 }
747
748 // Reset browser-level dirty tracking
749 $form.find('input, textarea, select').each(function () {
750 if (this.type !== 'checkbox' && this.type !== 'radio') {
751 this.defaultValue = this.value;
752 }
753 });
754
755 $form.find('input[type="checkbox"], input[type="radio"]').each(function () {
756 this.defaultChecked = this.checked;
757 });
758
759 // Reset WordPress dirty tracking
760 if (typeof wp !== 'undefined' && wp.autosave && wp.autosave.server) {
761 wp.autosave.server.postChanged = false;
762 }
763 }
764
765 jQuery(document).ready(function ($) {
766 $("body, .pano-error-close-btn").on("click", function (e) {
767 $("#error_occured").hide();
768 $('body').removeClass('error-overlay');
769 });
770
771 $(".panolenspreview, #error_occured").on("click", function (e) {
772 e.stopPropagation();
773 });
774 });
775
776 jQuery(document).ready(function ($) {
777 var previewtext = $('.previewtext').val();
778 if ("" != previewtext) {
779 $('.pnlm-load-button p').text(previewtext);
780 }
781 });
782
783 jQuery(document).ready(function ($) {
784
785 var flag_ok = false;
786 $('#save-post').on('click', function (e) {
787 var x = $(this).val();
788 if (!flag_ok) {
789 e.preventDefault();
790 $('.wpvr-loading').show();
791 var postid = $("#post_ID").val();
792 var panovideo = $("input[name='panovideo']:checked").val();
793 var videourl = $("input[name='video-attachment-url']").val();
794 var autoload = $("input[name='autoload']").is(':checked') ? 'on' : 'off';
795 var control = $("input[name='controls']").is(':checked') ? 'on' : 'off';
796 var compass = $("input[name='compass']:checked").val();
797 var defaultscene = $("input[name='default-scene-id']").val();
798 var preview = $("input[name='preview-attachment-url']").val();
799 var rotation = $("input[name='autorotation']").is(':checked') ? 'on' : 'off';
800 var autorotation = $("input[name='auto-rotation']").val();
801 var autorotationinactivedelay = $("input[name='auto-rotation-inactive-delay']").val();
802 var autorotationstopdelay = $("input[name='auto-rotation-stop-delay']").val();
803
804 var scenefadeduration = $("input[name='scene-fade-duration']").val();
805 var previewtext = $('.previewtext').val();
806
807 if ($('.scene-setup')[0]) {
808 var panodata = $('.scene-setup').repeaterVal();
809 var panolist = JSON.stringify(panodata);
810 } else {
811 var panodata = '';
812 var panolist = '';
813 }
814
815 //get the checklist data
816 var checklistData = {};
817 var checklistKeys = [
818 'scene',
819 'media',
820 'default',
821 'hotspots',
822 'movement-controls',
823 'publish'
824 ];
825
826 if(wpvr_localize?.is_wpvr_pro_active){
827 checklistKeys.push('zoom-controls');
828 }
829
830 checklistKeys.forEach(function (key) {
831 checklistData['wpvr_check_' + key] = document.getElementById('wpvr-check-' + key).checked;
832 });
833
834 updateProgress();
835
836 jQuery.ajax({
837
838 type: "POST",
839 url: ajaxurl,
840 data: {
841 action: "wpvr_save",
842 nonce : wpvr_obj.ajax_nonce,
843 postid: postid,
844 panovideo: panovideo,
845 videourl: videourl,
846 control: control,
847 compass: compass,
848 autoload: autoload,
849 panodata: panolist,
850 defaultscene: defaultscene,
851 preview: preview,
852 rotation: rotation,
853 autorotation: autorotation,
854 autorotationinactivedelay: autorotationinactivedelay,
855 autorotationstopdelay: autorotationstopdelay,
856 scenefadeduration: scenefadeduration,
857 previewtext: previewtext,
858 checklistData: checklistData
859 },
860
861 success: function (response) {
862 $('.wpvr-loading').hide();
863 if (response.success == false) {
864 $('#error_occured').show();
865 $('#error_occured').html(response.data);
866 $('#error_occuredpub').show();
867 $('#error_occuredpub').html(response.data);
868
869 $('body').addClass('error-overlay');
870 $('html, body').animate({
871 scrollTop: $("#error_occured").offset().top
872 }, 500);
873 } else {
874
875 // Only check publish checkbox if post is actually published
876 if (response.data.post_status === 'publish') {
877 if(!$('#wpvr-check-publish').prop('checked')){
878 $('#wpvr-check-publish').prop('checked', true);
879 $('#wpvr-check-publish').closest('.wpvr-checklist-item').css('color', '#0E003C');
880 }
881 } else {
882 // Uncheck if it's a draft
883 if($('#wpvr-check-publish').prop('checked')){
884 $('#wpvr-check-publish').prop('checked', false);
885 $('#wpvr-check-publish').closest('.wpvr-checklist-item').css('color', '#73707D');
886 }
887 }
888
889 // Validate scene checkbox state after save
890 let sceneImageCount = $('.rex-pano-tab .single-scene .scene-left .scene-setting .form-group img')
891 .filter(function() {
892 return $(this).attr('src') && $(this).attr('src').trim() !== '';
893 })
894 .length;
895
896 if (sceneImageCount === 0) {
897 $('#wpvr-check-scene').prop('checked', false);
898 $('#wpvr-check-media').prop('checked', false);
899 $('#wpvr-check-scene').closest('.wpvr-checklist-item').css('color', '#73707D');
900 $('#wpvr-check-media').closest('.wpvr-checklist-item').css('color', '#73707D');
901 }
902
903 updateProgress();
904
905 flag_ok = true;
906 $('#save-post').trigger('click');
907 }
908 }
909 });
910 }
911 });
912 });
913
914 function wpvrSanitizeHtml(rawHtml) {
915 if (!rawHtml || typeof rawHtml !== 'string') return '';
916 var clean = rawHtml.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
917 try {
918 var parser = new DOMParser();
919 var doc = parser.parseFromString(clean, 'text/html');
920 var elements = doc.body.querySelectorAll('*');
921 for (var i = 0; i < elements.length; i++) {
922 var el = elements[i];
923 var tag = el.tagName.toLowerCase();
924 if (['script', 'object', 'embed', 'applet', 'link', 'meta', 'base'].indexOf(tag) !== -1) {
925 el.parentNode && el.parentNode.removeChild(el);
926 continue;
927 }
928 var attrs = el.attributes;
929 for (var a = attrs.length - 1; a >= 0; a--) {
930 var attrName = attrs[a].name.toLowerCase();
931 var attrVal = attrs[a].value;
932 if (attrName.indexOf('on') === 0) {
933 el.removeAttribute(attrs[a].name);
934 } else if (['href', 'src', 'action', 'formaction', 'xlink:href'].indexOf(attrName) !== -1) {
935 if (/^\s*(javascript|vbscript|data:text\/html):/i.test(attrVal)) {
936 el.removeAttribute(attrs[a].name);
937 }
938 }
939 }
940 }
941 return doc.body.innerHTML;
942 } catch (e) {
943 return clean.replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, '').replace(/\s*on\w+\s*=\s*[^\s>]+/gi, '');
944 }
945 }
946
947 function wpvrhotspot(hotSpotDiv, args) {
948 if (args) {
949 const hasTextContent = typeof args === 'string' && args.replace(/<[^>]*>/g, '').trim() !== '';
950 const hasMediaContent = typeof args === 'string' && /<(img|video|audio|iframe|embed|object)\b[^>]*>/i.test(args);
951 const hasOtherContent = typeof args === 'string' && args.replace(/<(p|br|div|span)\b[^>]*\/?>/gi, '').trim() !== '';
952
953 if (hasTextContent || hasMediaContent || hasOtherContent) {
954 const cleanArgs = wpvrSanitizeHtml(args.replace(/\\/g, ''));
955 $("#custom-ifram").html(cleanArgs);
956 $("#custom-ifram").fadeToggle();
957 $(".iframe-wrapper").toggleClass("show-modal");
958 }
959 }
960 }
961
962 function wpvrtooltip(hotSpotDiv, args) {
963 if (args) {
964 const hasTextContent = typeof args === 'string' && args.replace(/<[^>]*>/g, '').trim() !== '';
965 const hasMediaContent = typeof args === 'string' && /<(img|video|audio|iframe|embed|object)\b[^>]*>/i.test(args);
966 const hasOtherContent = typeof args === 'string' && args.replace(/<(p|br|div|span)\b[^>]*\/?>/gi, '').trim() !== '';
967
968 if (hasTextContent || hasMediaContent || hasOtherContent) {
969 const cleanArgs = wpvrSanitizeHtml(args.replace(/\\/g, ''));
970 hotSpotDiv.classList.add('custom-tooltip');
971
972 const span = document.createElement('p');
973 span.innerHTML = cleanArgs;
974 hotSpotDiv.appendChild(span);
975
976 span.style.marginLeft = -(span.scrollWidth - hotSpotDiv.offsetWidth) / 2 + 'px';
977 span.style.marginTop = -span.scrollHeight - 12 + 'px';
978
979 if (!document.getElementById('wpvr-tooltip-style')) {
980 const style = document.createElement('style');
981 style.id = 'wpvr-tooltip-style';
982 style.textContent = `
983 .table, .table td, .table th {
984 border: 1px solid #dee2e6;
985 border-collapse: collapse;
986 padding: 8px;
987 }
988 `;
989 document.head.appendChild(style);
990 }
991 }
992 }
993 }
994
995
996 jQuery(document).ready(function ($) {
997 $("#cross").on("click", function (e) {
998 e.preventDefault();
999 $("#custom-ifram").fadeOut();
1000 $(".iframe-wrapper").removeClass("show-modal");
1001 $('iframe').attr('src', $('iframe').attr('src'));
1002 });
1003 });
1004
1005 jQuery(document).ready(function ($) {
1006
1007 var i = $('.scene-nav li').eq(-2).find('span').attr('data-index');
1008 i = parseInt(i);
1009
1010 $('.scene-setup').repeater({
1011
1012 defaultValues: {
1013 'scene-type': 'equirectangular',
1014 'dscene': 'off',
1015 'ptyscene': 'off',
1016 'cvgscene': 'off',
1017 'chgscene': 'off',
1018 'czscene': 'off',
1019 },
1020 show: function () {
1021 $('textarea[name*=hotspot-content]').summernote({
1022 toolbar: [
1023 ['style', ['style']],
1024 ['font', ['bold', 'underline', 'clear']],
1025 ['fontname', ['fontname']],
1026 ['color', ['color']],
1027 ['para', ['ul', 'ol', 'paragraph']],
1028 ['table', ['table']],
1029 ['insert', ['link', 'picture', 'video']],
1030 ['view', ['codeview', 'help']],
1031 ],
1032 callbacks: {
1033 onInit: function() {
1034 var $editor = $(this);
1035 var $noteEditor = $editor.next('.note-editor');
1036
1037 // Intercept Video button click
1038 $noteEditor.on('click', 'button.note-btn[aria-label="Video"]', function(e) {
1039 // Small delay to check if cursor is on a video
1040 setTimeout(function() {
1041 // Get the current selection
1042 var range = $editor.summernote('createRange');
1043 if (range) {
1044 var $node = $(range.sc);
1045
1046 // Check if cursor is on a video iframe
1047 var $iframe = $node.closest('iframe.note-video-clip');
1048 if (!$iframe.length) {
1049 $iframe = $node.find('iframe.note-video-clip').first();
1050 }
1051
1052 if ($iframe.length && $iframe.attr('src')) {
1053 var embedUrl = $iframe.attr('src');
1054 var videoUrl = '';
1055
1056 // Extract YouTube URL
1057 if (embedUrl && (embedUrl.indexOf('youtube.com') > -1 || embedUrl.indexOf('youtu.be') > -1)) {
1058 var match = embedUrl.match(/embed\/([^?&]*)/);
1059 if (match && match[1]) {
1060 videoUrl = 'https://www.youtube.com/watch?v=' + match[1];
1061 }
1062 } else if (embedUrl) {
1063 videoUrl = embedUrl;
1064 }
1065
1066 // Show the video dialog
1067 $editor.summernote('videoDialog.show');
1068
1069 // Pre-populate the video URL in the dialog
1070 setTimeout(function() {
1071 var $urlInput = $('.note-video-url');
1072 if ($urlInput.length && videoUrl) {
1073 $urlInput.val(videoUrl);
1074 $urlInput.focus();
1075 }
1076 }, 150);
1077 }
1078 }
1079 }, 50);
1080 });
1081 },
1082 onKeyup: function(e) {
1083 var getHotspotContent = $(this).summernote('code').trim();
1084 var tempDiv = document.createElement('div');
1085 tempDiv.innerHTML = getHotspotContent;
1086 var plainText = tempDiv.textContent || tempDiv.innerText || '';
1087 plainText = plainText.replace(/\u00a0/g, '').trim();
1088 var getParent = $(this).parent();
1089 var getMainParent = getParent.parent();
1090 var getClickContent = getMainParent.find('.hotspot-url');
1091
1092 if (plainText.length > 0) {
1093 getClickContent.find('input[name*=hotspot-url]').val('');
1094 getClickContent.find('input[name*=hotspot-url]').attr('placeholder', 'You can set either a URL or an On-click content');
1095 getClickContent.find('input[name*=hotspot-url]').attr("disabled", true);
1096 } else {
1097 getClickContent.find('input[name*=hotspot-url]').attr("disabled", false);
1098 }
1099 }
1100 }
1101 });
1102 $('textarea[name*=hotspot-hover]').summernote({
1103 toolbar: [
1104 ['style', ['style']],
1105 ['font', ['bold', 'underline', 'clear']],
1106 ['fontname', ['fontname']],
1107 ['color', ['color']],
1108 ['para', ['ul', 'ol', 'paragraph']],
1109 ['table', ['table']],
1110 ['insert', ['link', 'picture', 'video']],
1111 ['view', ['codeview', 'help']],
1112 ],
1113 fontNames: ['Arial', 'Helvetica', 'Tahoma', 'Courier New', 'Verdana', 'Impact', 'Times New Roman', 'system-ui', 'Helvetica Neue'],
1114 callbacks: {
1115 onInit: function() {
1116 var $editor = $(this);
1117 var $noteEditor = $editor.next('.note-editor');
1118
1119 // Intercept Video button click
1120 $noteEditor.on('click', 'button.note-btn[aria-label="Video"]', function(e) {
1121 // Small delay to check if cursor is on a video
1122 setTimeout(function() {
1123 // Get the current selection
1124 var range = $editor.summernote('createRange');
1125 if (range) {
1126 var $node = $(range.sc);
1127
1128 // Check if cursor is on a video iframe
1129 var $iframe = $node.closest('iframe.note-video-clip');
1130 if (!$iframe.length) {
1131 $iframe = $node.find('iframe.note-video-clip').first();
1132 }
1133
1134 if ($iframe.length && $iframe.attr('src')) {
1135 var embedUrl = $iframe.attr('src');
1136 var videoUrl = '';
1137
1138 // Extract YouTube URL
1139 if (embedUrl && (embedUrl.indexOf('youtube.com') > -1 || embedUrl.indexOf('youtu.be') > -1)) {
1140 var match = embedUrl.match(/embed\/([^?&]*)/);
1141 if (match && match[1]) {
1142 videoUrl = 'https://www.youtube.com/watch?v=' + match[1];
1143 }
1144 } else if (embedUrl) {
1145 videoUrl = embedUrl;
1146 }
1147
1148 // Show the video dialog
1149 $editor.summernote('videoDialog.show');
1150
1151 // Pre-populate the video URL in the dialog
1152 setTimeout(function() {
1153 var $urlInput = $('.note-video-url');
1154 if ($urlInput.length && videoUrl) {
1155 $urlInput.val(videoUrl);
1156 $urlInput.focus();
1157 }
1158 }, 150);
1159 }
1160 }
1161 }, 50);
1162 });
1163
1164 // Override font name dropdown click handler for this specific editor
1165 $editor.next('.note-editor').find('.dropdown-fontname a').off('click').on('click', function(e) {
1166 e.preventDefault();
1167 var fontName = $(this).data('value') || $(this).text();
1168
1169 // Focus on the current editor
1170 $editor.summernote('focus');
1171
1172 // Use Summernote's built-in method to apply font
1173 try {
1174 // First, clear any existing font formatting
1175 var range = $editor.summernote('createRange');
1176 if (range && !range.isCollapsed()) {
1177 // Get selected text
1178 var selectedText = range.toString();
1179
1180 // Use Summernote's insertHTML to replace content
1181 var fontHtml = '<span style="font-family: ' + fontName + ';">' + selectedText + '</span>';
1182 $editor.summernote('insertHTML', fontHtml);
1183 } else {
1184 // No selection, use execCommand for typing
1185 $editor.summernote('focus');
1186 document.execCommand('fontName', false, fontName);
1187 }
1188 } catch (error) {
1189 console.log('Font application error, using fallback method');
1190 // Fallback method
1191 document.execCommand('fontName', false, fontName);
1192 }
1193
1194 // Update dropdown button text for this editor
1195 $(this).closest('.note-editor').find('.note-current-fontname').text(fontName);
1196
1197 // Close dropdown
1198 var $dropdownMenu = $(this).closest('.dropdown-menu');
1199 $dropdownMenu.removeClass('show').hide();
1200 $dropdownMenu.prev('.dropdown-toggle').removeClass('show').attr('aria-expanded', 'false');
1201
1202 // Trigger change event
1203 setTimeout(function() {
1204 $editor.trigger('summernote.change');
1205 }, 100);
1206 });
1207 },
1208
1209 // Clean up the content after any change
1210 onChange: function(contents, $editable) {
1211 // Debounce the cleanup to avoid conflicts
1212 clearTimeout(this.cleanupTimeout);
1213 this.cleanupTimeout = setTimeout(function() {
1214 // Remove all font-family styles from elements that shouldn't have them
1215 $editable.find('*:not(span)').each(function() {
1216 if (this.style && this.style.fontFamily) {
1217 this.style.fontFamily = '';
1218 }
1219 });
1220
1221 // Clean up empty spans
1222 $editable.find('span').each(function() {
1223 var $span = $(this);
1224 var text = $span.text().replace(/[\uFEFF\u200B-\u200D\u2060]/g, '').trim();
1225
1226 if (!text) {
1227 $span.remove();
1228 } else {
1229 // If span has other styles besides font-family, keep only font-family
1230 var fontFamily = $span.css('font-family');
1231 if (fontFamily && fontFamily !== 'inherit') {
1232 $span.attr('style', 'font-family: ' + fontFamily + ';');
1233 } else if (!fontFamily || fontFamily === 'inherit') {
1234 $span.contents().unwrap();
1235 }
1236 }
1237 });
1238
1239 // Remove nested spans with font-family
1240 $editable.find('span[style*="font-family"] span[style*="font-family"]').each(function() {
1241 $(this).contents().unwrap();
1242 });
1243 }, 200);
1244 }
1245 }
1246 });
1247 if ($(this).parents(".scene-setup").attr("data-limit").length > 0) {
1248 lastChildClicked = true;
1249 if ($(this).parents(".scene-setup").find("div[data-repeater-item]:not(.hotspot-setup div[data-repeater-item])").length <= $(this).parents(".scene-setup").attr("data-limit")) {
1250
1251 $(this).slideDown();
1252 $(this).removeClass('active');
1253
1254 i = i + 1;
1255 var scene = 'scene-' + i;
1256
1257 $(this).find(".title .scene-num").html(i);
1258
1259 $('<li><span data-index="' + i + '" data-href="#' + scene + '"><i class="fa fa-image"></i></span></li>').insertBefore($(this).parent().parent('.scene-setup').find('.scene-nav ul li:last-child'));
1260
1261 $(this).attr('id', scene);
1262 changehotspotid(i);
1263 $(this).siblings('.active').removeClass('active');
1264 $(this).addClass('active');
1265 $(this).find(".sceneid").val(generateRandomString(8));
1266 setTimeout(changeicon, 1000);
1267 } else {
1268 $('.pano-alert .pano-error-message').html('<span class="pano-error-title">Limit Reached</span><p> You can add up to 5 scenes on each tour in the Free version. Upgrade to Pro to create tours with unlimited scenes.</p>');
1269 $('body').addClass('error-overlay2');
1270 $('.pano-alert').addClass('pano-default-warning').show();
1271 $(this).remove();
1272 }
1273 } else {
1274 jQuery(this).slideDown();
1275 $(this).removeClass('active');
1276
1277 i = i + 1;
1278 var scene = 'scene-' + i;
1279 $(this).find(".title .scene-num").html(i);
1280 $('<li><span data-index="' + i + '" data-href="#' + scene + '"><i class="fa fa-image"></i></span></li>').insertBefore($(this).parent().parent('.scene-setup').find('.scene-nav ul li:last-child'));
1281 $(this).attr('id', scene);
1282 changehotspotid(i);
1283 }
1284
1285 $(this).hide();
1286
1287 //tab active setup
1288 $('#wpvr_active_scenes').val(i);
1289 $('#wpvr_active_hotspot').val(1);
1290 },
1291 hide: function (deleteElement) {
1292 var hide_id = $(this).attr("id");
1293 var _hide_id = hide_id.split('-').pop();
1294 hide_id = "#" + hide_id;
1295
1296 var current = $(this).attr('id');
1297 var fchild = $('.single-scene:nth-child(2)').attr('id');
1298 // var fchild = $(this).parent().children(":first").attr('id');
1299
1300
1301 var elementcontains = $(this).attr("id");
1302 var str1 = 'scene';
1303 var str2 = 'hotspot';
1304 if (elementcontains.indexOf(str1) != -1 && elementcontains.indexOf(str2) == -1) {
1305
1306 var _this = $(this);
1307
1308 if (confirm('Are you sure you want to delete?')) {
1309 jQuery(_this).slideUp(deleteElement);
1310 if (current == fchild) {
1311 $(_this).next().addClass("active");
1312 $(_this).parent().parent('.scene-setup').find('.scene-nav li span[data-href="' + hide_id + '"]').parent("li").next().addClass("active");
1313 $(_this).parent().parent('.scene-setup').find('.scene-nav li span[data-href="' + hide_id + '"]').parent("li").next().children("span").trigger("click");
1314 } else {
1315 $(_this).prev().addClass("active");
1316 $(_this).parent().parent('.scene-setup').find('.scene-nav li span[data-href="' + hide_id + '"]').parent("li").prev().addClass("active");
1317 $(_this).parent().parent('.scene-setup').find('.scene-nav li span[data-href="' + hide_id + '"]').parent("li").prev().children("span").trigger("click");
1318 }
1319 $(_this).parent().parent('.scene-setup').find('.scene-nav li span[data-href="' + hide_id + '"]').parent("li").remove();
1320 setTimeout(deleteinfodata, 1000);
1321
1322 //tab active setup
1323 if (parseInt(_hide_id) - 1 > 0) {
1324 $('#wpvr_active_scenes').val(parseInt(_hide_id) - 1);
1325 } else {
1326 $('#wpvr_active_scenes').val(1);
1327 }
1328 $('#wpvr_active_hotspot').val(1);
1329
1330
1331 setTimeout(function(){
1332 let sceneImageCount = $('.rex-pano-tab .single-scene .scene-left .scene-setting .form-group img')
1333 .filter(function() {
1334 return $(this).attr('src') && $(this).attr('src').trim() !== '';
1335 })
1336 .length;
1337
1338 let defaultScene = false;
1339 let hotspotCheck = false;
1340
1341 let $sceneCheckbox = $('#wpvr-check-scene');
1342 let $mediaCheckbox = $('#wpvr-check-media');
1343 let $hotspotCheck = $('#wpvr-check-hotspots');
1344 let $defaultCheck = $('#wpvr-check-default');
1345
1346 $('select').each(function() {
1347 if (/^scene-list\[\d+\]\[dscene\]$/.test($(this).attr('name'))) {
1348 let selectedValue = $(this).val();
1349 if('on' === selectedValue){
1350 defaultScene = true;
1351 }
1352 }
1353 });
1354
1355 if (sceneImageCount === 0) {
1356 $sceneCheckbox.prop('checked', false);
1357 $mediaCheckbox.prop('checked', false);
1358 $sceneCheckbox.closest('.wpvr-checklist-item').css('color', '#73707D');
1359 $mediaCheckbox.closest('.wpvr-checklist-item').css('color', '#73707D');
1360 }
1361
1362 if(!defaultScene){
1363 $defaultCheck.prop('checked', false);
1364 $defaultCheck.closest('.wpvr-checklist-item').css('color', '#73707D');
1365 }
1366
1367 let pitchInputs = document.querySelectorAll('.hotspot-pitch');
1368 for (let pitchInput of pitchInputs) {
1369 if (pitchInput.value.trim() !== '') {
1370 hotspotCheck = true;
1371 }
1372 }
1373
1374 if(!hotspotCheck)
1375 {
1376 $hotspotCheck.prop('checked', false);
1377 $hotspotCheck.closest('.wpvr-checklist-item').css('color', '#73707D');
1378 }
1379 updateProgress();
1380 }, 500);
1381 }
1382
1383 }
1384 },
1385 repeaters: [{
1386 selector: '.hotspot-setup',
1387 defaultValues: {
1388 'hotspot-type': 'info',
1389 'hotspot-customclass-pro': 'none',
1390 },
1391 show: function () {
1392 $('textarea[name*=hotspot-content]').summernote({
1393 toolbar: [
1394 ['style', ['style']],
1395 ['font', ['bold', 'underline', 'clear']],
1396 ['fontname', ['fontname']],
1397 ['color', ['color']],
1398 ['para', ['ul', 'ol', 'paragraph']],
1399 ['table', ['table']],
1400 ['insert', ['link', 'picture', 'video']],
1401 ['view', ['codeview', 'help']],
1402 ],
1403 callbacks: {
1404 onInit: function() {
1405 var $editor = $(this);
1406 var $noteEditor = $editor.next('.note-editor');
1407
1408 // Intercept Video button click
1409 $noteEditor.on('click', 'button.note-btn[aria-label="Video"]', function(e) {
1410 // Small delay to check if cursor is on a video
1411 setTimeout(function() {
1412 // Get the current selection
1413 var range = $editor.summernote('createRange');
1414 if (range) {
1415 var $node = $(range.sc);
1416
1417 // Check if cursor is on a video iframe
1418 var $iframe = $node.closest('iframe.note-video-clip');
1419 if (!$iframe.length) {
1420 $iframe = $node.find('iframe.note-video-clip').first();
1421 }
1422
1423 if ($iframe.length && $iframe.attr('src')) {
1424 var embedUrl = $iframe.attr('src');
1425 var videoUrl = '';
1426
1427 // Extract YouTube URL
1428 if (embedUrl && (embedUrl.indexOf('youtube.com') > -1 || embedUrl.indexOf('youtu.be') > -1)) {
1429 var match = embedUrl.match(/embed\/([^?&]*)/);
1430 if (match && match[1]) {
1431 videoUrl = 'https://www.youtube.com/watch?v=' + match[1];
1432 }
1433 } else if (embedUrl) {
1434 videoUrl = embedUrl;
1435 }
1436
1437 // Show the video dialog
1438 $editor.summernote('videoDialog.show');
1439
1440 // Pre-populate the video URL in the dialog
1441 setTimeout(function() {
1442 var $urlInput = $('.note-video-url');
1443 if ($urlInput.length && videoUrl) {
1444 $urlInput.val(videoUrl);
1445 $urlInput.focus();
1446 }
1447 }, 150);
1448 }
1449 }
1450 }, 50);
1451 });
1452 },
1453 onKeyup: function(e) {
1454 var getHotspotContent = $(this).summernote('code').trim();
1455 var tempDiv = document.createElement('div');
1456 tempDiv.innerHTML = getHotspotContent;
1457 var plainText = tempDiv.textContent || tempDiv.innerText || '';
1458 plainText = plainText.replace(/\u00a0/g, '').trim();
1459 var getParent = $(this).parent();
1460 var getMainParent = getParent.parent();
1461 var getClickContent = getMainParent.find('.hotspot-url');
1462
1463 if (plainText.length > 0) {
1464 getClickContent.find('input[name*=hotspot-url]').val('');
1465 getClickContent.find('input[name*=hotspot-url]').attr('placeholder', 'You can set either a URL or an On-click content');
1466 getClickContent.find('input[name*=hotspot-url]').attr("disabled", true);
1467 } else {
1468 getClickContent.find('input[name*=hotspot-url]').attr("disabled", false);
1469 }
1470 }
1471 }
1472 });
1473 $('textarea[name*=hotspot-hover]').summernote({
1474 toolbar: [
1475 ['style', ['style']],
1476 ['font', ['bold', 'underline', 'clear']],
1477 ['fontname', ['fontname']],
1478 ['color', ['color']],
1479 ['para', ['ul', 'ol', 'paragraph']],
1480 ['table', ['table']],
1481 ['insert', ['link', 'picture', 'video']],
1482 ['view', ['codeview', 'help']],
1483 ],
1484 fontNames: ['Arial', 'Helvetica', 'Tahoma', 'Courier New', 'Verdana', 'Impact', 'Times New Roman', 'system-ui', 'Helvetica Neue'],
1485 callbacks: {
1486 onInit: function() {
1487 var $editor = $(this);
1488 var $noteEditor = $editor.next('.note-editor');
1489
1490 // Intercept Video button click
1491 $noteEditor.on('click', 'button.note-btn[aria-label="Video"]', function(e) {
1492 // Small delay to check if cursor is on a video
1493 setTimeout(function() {
1494 // Get the current selection
1495 var range = $editor.summernote('createRange');
1496 if (range) {
1497 var $node = $(range.sc);
1498
1499 // Check if cursor is on a video iframe
1500 var $iframe = $node.closest('iframe.note-video-clip');
1501 if (!$iframe.length) {
1502 $iframe = $node.find('iframe.note-video-clip').first();
1503 }
1504
1505 if ($iframe.length && $iframe.attr('src')) {
1506 var embedUrl = $iframe.attr('src');
1507 var videoUrl = '';
1508
1509 // Extract YouTube URL
1510 if (embedUrl && (embedUrl.indexOf('youtube.com') > -1 || embedUrl.indexOf('youtu.be') > -1)) {
1511 var match = embedUrl.match(/embed\/([^?&]*)/);
1512 if (match && match[1]) {
1513 videoUrl = 'https://www.youtube.com/watch?v=' + match[1];
1514 }
1515 } else if (embedUrl) {
1516 videoUrl = embedUrl;
1517 }
1518
1519 // Show the video dialog
1520 $editor.summernote('videoDialog.show');
1521
1522 // Pre-populate the video URL in the dialog
1523 setTimeout(function() {
1524 var $urlInput = $('.note-video-url');
1525 if ($urlInput.length && videoUrl) {
1526 $urlInput.val(videoUrl);
1527 $urlInput.focus();
1528 }
1529 }, 150);
1530 }
1531 }
1532 }, 50);
1533 });
1534
1535 // Override font name dropdown click handler for this specific editor
1536 $editor.next('.note-editor').find('.dropdown-fontname a').off('click').on('click', function(e) {
1537 e.preventDefault();
1538 var fontName = $(this).data('value') || $(this).text();
1539
1540 // Focus on the current editor
1541 $editor.summernote('focus');
1542
1543 // Use Summernote's built-in method to apply font
1544 try {
1545 // First, clear any existing font formatting
1546 var range = $editor.summernote('createRange');
1547 if (range && !range.isCollapsed()) {
1548 // Get selected text
1549 var selectedText = range.toString();
1550
1551 // Use Summernote's insertHTML to replace content
1552 var fontHtml = '<span style="font-family: ' + fontName + ';">' + selectedText + '</span>';
1553 $editor.summernote('insertHTML', fontHtml);
1554 } else {
1555 // No selection, use execCommand for typing
1556 $editor.summernote('focus');
1557 document.execCommand('fontName', false, fontName);
1558 }
1559 } catch (error) {
1560 console.log('Font application error, using fallback method');
1561 // Fallback method
1562 document.execCommand('fontName', false, fontName);
1563 }
1564
1565 // Update dropdown button text for this editor
1566 $(this).closest('.note-editor').find('.note-current-fontname').text(fontName);
1567
1568 // Close dropdown
1569 var $dropdownMenu = $(this).closest('.dropdown-menu');
1570 $dropdownMenu.removeClass('show').hide();
1571 $dropdownMenu.prev('.dropdown-toggle').removeClass('show').attr('aria-expanded', 'false');
1572
1573 // Trigger change event
1574 setTimeout(function() {
1575 $editor.trigger('summernote.change');
1576 }, 100);
1577 });
1578 },
1579
1580 // Clean up the content after any change
1581 onChange: function(contents, $editable) {
1582 // Debounce the cleanup to avoid conflicts
1583 clearTimeout(this.cleanupTimeout);
1584 this.cleanupTimeout = setTimeout(function() {
1585 // Remove all font-family styles from elements that shouldn't have them
1586 $editable.find('*:not(span)').each(function() {
1587 if (this.style && this.style.fontFamily) {
1588 this.style.fontFamily = '';
1589 }
1590 });
1591
1592 // Clean up empty spans
1593 $editable.find('span').each(function() {
1594 var $span = $(this);
1595 var text = $span.text().replace(/[\uFEFF\u200B-\u200D\u2060]/g, '').trim();
1596
1597 if (!text) {
1598 $span.remove();
1599 } else {
1600 // If span has other styles besides font-family, keep only font-family
1601 var fontFamily = $span.css('font-family');
1602 if (fontFamily && fontFamily !== 'inherit') {
1603 $span.attr('style', 'font-family: ' + fontFamily + ';');
1604 } else if (!fontFamily || fontFamily === 'inherit') {
1605 $span.contents().unwrap();
1606 }
1607 }
1608 });
1609
1610 // Remove nested spans with font-family
1611 $editable.find('span[style*="font-family"] span[style*="font-family"]').each(function() {
1612 $(this).contents().unwrap();
1613 });
1614 }, 200);
1615 }
1616 }
1617 });
1618 if ($(this).parents(".hotspot-setup").attr("data-limit").length > 0) {
1619
1620 if ($(this).parents(".hotspot-setup").find("div[data-repeater-item]").length <= $(this).parents(".hotspot-setup").attr("data-limit")) {
1621
1622 $(this).slideDown();
1623 $(this).removeClass('active');
1624 $(this).siblings('.active').removeClass('active');
1625 $(this).addClass('active');
1626 j = parseInt(j);
1627 j = j + 1;
1628 var parent_scene = $(this).parent().parent().parent('.single-scene.active').attr('id');
1629 scene_parent = parent_scene;
1630 var hotspot = parent_scene + '-hotspot-' + j;
1631
1632 var replace_string = parent_scene.replace("scene-", "");
1633
1634 $(this).find(".title .hotspot-num").html(j);
1635 $(this).find(".title .scene-num").html(replace_string);
1636
1637 $('<li><span data-index="' + j + '" data-href="#' + hotspot + '"><i class="far fa-dot-circle"></i></span></li>').insertBefore($(this).parent().parent('.hotspot-setup').find('.hotspot-nav ul li:last-child'));
1638
1639 $(this).attr('id', hotspot);
1640
1641 setTimeout(changeicon, 1000);
1642 } else {
1643 $('.pano-alert .pano-error-message').html('<span class="pano-error-title">Limit Reached</span><p> You can add up to 5 hotspots on each scene in the Free version. <br> Upgrade to Pro to add an unlimited number of hotspots.</p>');
1644 $('body').addClass('error-overlay2');
1645 $('.pano-alert').addClass('pano-default-warning').show();
1646 $(this).remove();
1647 }
1648 } else {
1649 jQuery(this).slideDown();
1650 $(this).removeClass('active');
1651 j = parseInt(j);
1652 j = j + 1;
1653 var parent_scene = $(this).parent().parent().parent('.single-scene.active').attr('id');
1654 var hotspot = parent_scene + '-hotspot-' + j;
1655
1656 var replace_string = parent_scene.replace("scene-", "");
1657
1658 $(this).find(".title .hotspot-num").html(j);
1659 $(this).find(".title .scene-num").html(replace_string);
1660
1661 $('<li><span data-index="' + j + '" data-href="#' + hotspot + '"><i class="far fa-dot-circle"></i></span></li>').insertBefore($(this).parent().parent('.hotspot-setup').find('.hotspot-nav ul li:last-child'));
1662
1663 $(this).attr('id', hotspot);
1664 }
1665 $('#wpvr_active_hotspot').val(j);
1666 },
1667 hide: function (deleteElement) {
1668 var hotspot_hide_id = $(this).attr("id");
1669 var _hide_id = hotspot_hide_id.split('-').pop();
1670 hotspot_hide_id = "#" + hotspot_hide_id;
1671 var hotspot_current = $(this).attr('id');
1672 var hotspot_fchild = $(this).parent().children(":first").attr('id');
1673
1674 var hpelementcontains = $(this).attr("id");
1675 var hpstr1 = 'scene';
1676 var hpstr2 = 'hotspot';
1677 if (hpelementcontains.indexOf(hpstr1) != -1 && hpelementcontains.indexOf(hpstr2) != -1) {
1678
1679 var _this = $(this);
1680
1681 if (confirm('Are you sure you want to delete?')) {
1682 jQuery(_this).slideUp(deleteElement);
1683 if (hotspot_current == hotspot_fchild) {
1684 $(_this).next().addClass("active");
1685 $(_this).parent().parent('.hotspot-setup').find('.hotspot-nav li span[data-href="' + hotspot_hide_id + '"]').parent("li").next().addClass("active");
1686
1687 } else {
1688 $(_this).prev().addClass("active");
1689 $(_this).parent().parent('.hotspot-setup').find('.hotspot-nav li span[data-href="' + hotspot_hide_id + '"]').parent("li").prev().addClass("active");
1690 }
1691
1692 $(_this).parent().parent('.hotspot-setup').find('.hotspot-nav li:not(:last-child) span[data-href="' + hotspot_hide_id + '"]').parent("li").remove();
1693
1694 //tab active setup
1695 if (parseInt(_hide_id) - 1 > 0) {
1696 $('#wpvr_active_hotspot').val(parseInt(_hide_id) - 1);
1697 } else {
1698 $('#wpvr_active_hotspot').val(1);
1699 }
1700
1701 setTimeout(function(){
1702 let yawInputs = $('.hotspot-yaw');
1703 let pitchInputs = $('.hotspot-pitch');
1704 let hasYawValue = false;
1705 let hasPitchValue = false;
1706
1707 yawInputs.each(function() {
1708 if ($(this).val() && $(this).val().trim() !== '') {
1709 hasYawValue = true;
1710 return false; // break loop
1711 }
1712 });
1713 pitchInputs.each(function() {
1714 if ($(this).val() && $(this).val().trim() !== '') {
1715 hasPitchValue = true;
1716 return false; // break loop
1717 }
1718 });
1719
1720 let $hotspotCheckbox = $('#wpvr-check-hotspots');
1721
1722 if (!hasYawValue && !hasPitchValue) {
1723 $hotspotCheckbox.prop('checked', false);
1724 $hotspotCheckbox.closest('.wpvr-checklist-item').css('color', '#73707D');
1725 } else {
1726 $hotspotCheckbox.prop('checked', true);
1727 $hotspotCheckbox.closest('.wpvr-checklist-item').css('color', '#0E003C');
1728 }
1729 updateProgress();
1730 },500);
1731 }
1732 }
1733 },
1734
1735 }]
1736 });
1737 });
1738
1739 $(document).on("click", ".upload-scene-wrapper", function (event) {
1740 $(".scene-nav ul li:last-child span").trigger("click");
1741 $(".scene-upload").last().trigger("click");
1742 })
1743
1744 $(document).on("click", ".upload-scene-wrapper-first", function (event) {
1745 $(".scene-upload").trigger("click");
1746 })
1747
1748 $(document).on("click", ".scene-upload", function (event) {
1749 event.preventDefault();
1750 scene_upload_parent = $(this).parent('.form-group');
1751
1752 if (scene_uploader) {
1753 scene_uploader.open();
1754 return;
1755 }
1756
1757 scene_uploader = wp.media({
1758 title: $(this).data('uploader_title'),
1759 button: {
1760 text: $(this).data('uploader_button_text'),
1761 },
1762 library: {
1763 type: ['image']
1764 },
1765 multiple: false
1766 });
1767
1768 scene_uploader.on('select', function () {
1769
1770 var attachment = scene_uploader.state().get('selection').first().toJSON();
1771 scene_uploader.close();
1772
1773 var $selectedSceneUploadParent = scene_upload_parent;
1774
1775 function applySelectedSceneImage(imageUrl) {
1776 var siteProtocol = window.location.protocol;
1777 var normalizedImageUrl;
1778
1779 try {
1780 normalizedImageUrl = new URL(imageUrl, window.location.origin);
1781 } catch (error) {
1782 return;
1783 }
1784
1785 imageUrl = normalizedImageUrl.href;
1786 var imageProtocol = normalizedImageUrl.protocol;
1787
1788 $('.rex-add-coordinates .mixed-content-warning, .rex-add-coordinates .mixed-content-doc-link').remove();
1789
1790 if (siteProtocol !== imageProtocol) {
1791
1792 // Create warning message
1793 var $warningBox = $('<div>', {
1794 text: "You're loading an image over " + imageProtocol.replace(':', '').toUpperCase() +
1795 " on a site using " + siteProtocol.replace(':', '').toUpperCase() +
1796 ". This may cause a mixed content issue.",
1797 class: 'mixed-content-warning',
1798 css: {
1799 color: 'red',
1800 marginTop: '35px',
1801 }
1802 });
1803
1804 // Create doc link
1805 var $docLink = $('<a>', {
1806 href: 'https://rextheme.com/docs/wp-vr-tour-not-displaying/',
1807 text: 'View fix guide',
1808 target: '_blank',
1809 class: 'mixed-content-doc-link',
1810 css: {
1811 display: 'block',
1812 color: '#0073aa',
1813 textDecoration: 'underline'
1814 }
1815 }).on('click', function () {
1816 $(this).blur(); // Remove focus after click
1817 });
1818
1819 // Prepend warning and link to the top of the container
1820 $('.rex-add-coordinates').prepend($warningBox, $docLink);
1821 }
1822
1823 $selectedSceneUploadParent.find('.scene-attachment-url').val(imageUrl);
1824 $selectedSceneUploadParent.find('img').attr('src', imageUrl).show();
1825
1826 setTimeout(function () {
1827 if (!$('#wpvr-check-scene').is(':checked')) {
1828 $('#wpvr-check-scene').prop('checked', true);
1829 $('#wpvr-check-scene').closest('.wpvr-checklist-item').css('color', '#0E003C');
1830 }
1831
1832 if (!$('#wpvr-check-media').is(':checked')) {
1833 $('#wpvr-check-media').prop('checked', true);
1834 $('#wpvr-check-media').closest('.wpvr-checklist-item').css('color', '#0E003C');
1835 }
1836
1837 updateProgress();
1838
1839 $('.panolenspreview').trigger('click');
1840 }, 1000);
1841 }
1842
1843 if (window.WPVRImageResizeWarning) {
1844 try {
1845 window.WPVRImageResizeWarning.handleSelection(
1846 attachment,
1847 applySelectedSceneImage
1848 );
1849 } catch (error) {
1850 applySelectedSceneImage(attachment.url);
1851 }
1852 } else {
1853 applySelectedSceneImage(attachment.url);
1854 }
1855
1856
1857 });
1858
1859 scene_uploader.open();
1860 });
1861
1862 $(document).on("click", ".video-upload", function (event) {
1863 event.preventDefault();
1864
1865 var parent = $(this).parent('.form-group');
1866
1867 var video_uploader = wp.media({
1868 title: $(this).data('uploader_title'),
1869 button: {
1870 text: $(this).data('uploader_button_text'),
1871 },
1872 library: {
1873 type: ['video/mp4']
1874 },
1875 multiple: false
1876 });
1877
1878 video_uploader.on('select', function () {
1879 var attachment = video_uploader.state().get('selection').first().toJSON();
1880 parent.find('.video-attachment-url').val(attachment.url);
1881 });
1882
1883 video_uploader.open();
1884 });
1885
1886 $(document).on("click", ".preview-upload", function (event) {
1887 event.preventDefault();
1888 var parent = $(this).parent('.form-group');
1889
1890 var preview_uploader = wp.media({
1891 title: $(this).data('uploader_title'),
1892 button: {
1893 text: $(this).data('uploader_button_text'),
1894 },
1895 library: {
1896 type: ['image']
1897 },
1898 multiple: false
1899 });
1900
1901 preview_uploader.on('select', function () {
1902 var attachment = preview_uploader.state().get('selection').first().toJSON();
1903 parent.find('.preview-attachment-url').val(attachment.url);
1904 parent.find('.img-upload-frame').css('background-image', 'url(' + attachment.url + ')');
1905 parent.find('.img-upload-frame').addClass('img-uploaded');
1906 parent.find('.remove-attachment').show();
1907 });
1908
1909 preview_uploader.open();
1910 });
1911
1912 //----remove tour preview image----
1913 $(document).on("click", ".remove-attachment", function (event) {
1914 $(this).hide();
1915 parent = $(this).parents('.form-group');
1916
1917 parent.find('.preview-attachment-url').val('');
1918 parent.find('.img-upload-frame').css('background-image', '');
1919 parent.find('.img-upload-frame').removeClass('img-uploaded');
1920 });
1921
1922
1923 $(document).on("change", "select[name*=hotspot-type]", function (event) {
1924
1925 var getparent = $(this).parent();
1926 var getvalue = $(this).val();
1927 if (getvalue == 'info') {
1928 getparent.find('.hotspot-scene').hide();
1929 getparent.find('.hotspot-scene input').val('');
1930 getparent.find('.hotspot-scene .hotspotscene').val('none');
1931 getparent.find('.hotspot-url').show();
1932 getparent.find('.s_tab').show();
1933 getparent.find('.hotspot-content').show();
1934 getparent.find('input[name*=hotspot-url]').attr("disabled",false)
1935 getparent.find('textarea[name*=hotspot-content]').next().find(".note-editable").attr("contenteditable", true);
1936 } else {
1937 getparent.find('.hotspot-scene').show();
1938 getparent.find('.hotspot-url').hide();
1939 getparent.find('.hotspot-url input').val('');
1940 getparent.find('.s_tab').hide();
1941 getparent.find('.s_tab input').val('off');
1942 getparent.find('.s_tab input').removeAttr('checked');
1943 getparent.find('.hotspot-content').hide();
1944 getparent.find('.hotspot-content textarea').val('');
1945 getparent.find('textarea[name*=hotspot-content]').next().find(".note-editable").html('');
1946 }
1947 });
1948 $(document).ready(function ($){
1949 $(document).on("keyup","input[name*=hotspot-url]",function (){
1950 var getHotspotUrl = $(this).val();
1951 var getParent = $(this).parent();
1952 var getMainParent = getParent.parent()
1953 var getClickContent = getMainParent.find('.hotspot-content')
1954 if(getHotspotUrl.length > 0){
1955 getClickContent.find('textarea').val('')
1956 getClickContent.find('textarea').attr('placeholder','You can set either a URL or an On-click content')
1957 getClickContent.find('textarea').attr("disabled",true)
1958 getClickContent.find('textarea[name*=hotspot-content]').next().find(".note-editable").attr("contenteditable", false);
1959 getClickContent.find('textarea[name*=hotspot-content]').next().find(".note-editable").html('');
1960
1961 }else{
1962 getClickContent.find('textarea').attr("disabled",false)
1963 getClickContent.find('textarea[name*=hotspot-content]').next().find(".note-editable").attr("contenteditable", true);
1964 }
1965 })
1966
1967 $(document).on("keyup","textarea[name*=hotspot-content]",function (){
1968 var getHotspotContent = $(this).summernote('code').trim();
1969 if (getHotspotContent === '<br>' || getHotspotContent === '<p><br></p>') {
1970 getHotspotContent = '';
1971 }
1972 var getParent = $(this).parent();
1973 var getMainParent = getParent.parent()
1974 var getClickContent = getMainParent.find('.hotspot-url')
1975 if(getHotspotContent.length > 0){
1976 getClickContent.find('input[name*=hotspot-url').val('')
1977 getClickContent.find('input[name*=hotspot-url').attr('placeholder','You can set either a URL or an On-click content')
1978 getClickContent.find('input[name*=hotspot-url]').attr("disabled",true)
1979 }else{
1980 getClickContent.find('input[name*=hotspot-url]').attr("disabled",false)
1981 }
1982 })
1983 })
1984
1985
1986 $(document).on("click", ".pano-error-close-btn", function (e) {
1987 e.preventDefault();
1988 $('.wpvr-delete-alert-wrapper').css('display', 'none');
1989 $('.wpvr-delete-alert-wrapper').hide();
1990 });
1991
1992 $(document).on("change", "input[type=radio][name=panovideo]", function (event) {
1993 var getvalue = $(this).val();
1994
1995 if (getvalue == 'on') {
1996 $('#confirm_text').html(`${window.wpvr_localize.VideoTourNotice}`);
1997 $('.wpvr-delete-alert-wrapper').css('display', 'flex');
1998 } else {
1999 $('.wpvr-delete-alert-wrapper').css('display', 'none');
2000 // $(".video-setting").hide();
2001
2002 $("li.general").show();
2003 $("li.scene").show();
2004 $("li.hotspot").show();
2005 $("li.streetview").show();
2006 $(".video-setting").hide();
2007 toggleSceneGallery(null, 'off');
2008 }
2009
2010 $(document).on("click", ".wpvr-delete-confirm-btn .cancel,.wpvr-delete-alert-wrapper .cross", function (e) {
2011 e.preventDefault();
2012 $('.wpvr-delete-alert-wrapper').css('display', 'none');
2013 $('.wpvr-delete-alert-wrapper').hide();
2014
2015 $(".video_on").prop('checked', false);
2016 $(".video_off").prop('checked', true);
2017
2018 $("li.general").show();
2019 $("li.scene").show();
2020 $("li.hotspot").show();
2021 $("li.streetview").show();
2022 $(".video-setting").hide();
2023 toggleSceneGallery(null, 'off');
2024
2025 });
2026
2027 $(document).on("click", ".wpvr-delete-confirm-btn .yes", function (e) {
2028 e.preventDefault();
2029 $('.wpvr-delete-alert-wrapper').css('display', 'none');
2030 $('.wpvr-delete-alert-wrapper').hide();
2031
2032 $(".video_off").prop('checked', false);
2033 $(".video_on").prop('checked', true);
2034 $(".video-setting").show();
2035 $("li.general").hide();
2036 $("li.scene").hide();
2037 $("li.hotspot").hide();
2038 $("li.streetview").hide();
2039 toggleSceneGallery(null, 'on');
2040
2041 });
2042 });
2043
2044 jQuery(document).ready(function ($) {
2045 let detect_scene_1_data = $('#scene-1').find('.sceneid').val();
2046 if(detect_scene_1_data === "") {
2047 $('#scene-1').find('.sceneid').val(generateRandomString(8));
2048 }
2049 });
2050
2051 function generateRandomString(length) {
2052 var result = '';
2053 var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
2054 var charactersLength = characters.length;
2055
2056 for (var i = 0; i < length; i++) {
2057 var randomIndex = Math.floor(Math.random() * charactersLength);
2058 result += characters.charAt(randomIndex);
2059 }
2060
2061 return result;
2062 }
2063 function prepare_hotspot_configuration_data() {
2064 var datacoords = $('#panodata').text().split(',');
2065 var pitchsplit = datacoords[0];
2066 var pitch = pitchsplit.split(':');
2067 var yawsplit = datacoords[1];
2068 var yaw = yawsplit.split(':');
2069 let detect_active_hotspot_id = $('div.single-scene.rex-pano-tab.active').children('div.hotspot-setup.rex-pano-sub-tabs').children('div.rex-pano-tab-content').children('div.single-hotspot.rex-pano-tab.active.clearfix').find("#hotspot-title").val();
2070 if(detect_active_hotspot_id === "" || detect_active_hotspot_id == undefined) {
2071 $('div.single-scene.rex-pano-tab.active').children('div.hotspot-setup.rex-pano-sub-tabs').children('div.rex-pano-tab-content').children('div.single-hotspot.rex-pano-tab.active.clearfix').find("#hotspot-title").val(generateRandomString(8));
2072 }
2073 $('div.single-scene.rex-pano-tab.active').children('div.hotspot-setup.rex-pano-sub-tabs').children('div.rex-pano-tab-content').children('div.single-hotspot.rex-pano-tab.active.clearfix').find('.hotspot-pitch').val(pitch[1].trim());
2074 $('div.single-scene.rex-pano-tab.active').children('div.hotspot-setup.rex-pano-sub-tabs').children('div.rex-pano-tab-content').children('div.single-hotspot.rex-pano-tab.active.clearfix').find('.hotspot-yaw').val(yaw[1].trim());
2075 }
2076
2077 function register_hotspot() {
2078 $('.panolenspreview').trigger('click');
2079 }
2080
2081 $(document).on("click", ".toppitch", function (event) {
2082 $.when(prepare_hotspot_configuration_data()).done(function() {
2083 register_hotspot();
2084 });
2085 });
2086
2087 jQuery(document).ready(function ($) {
2088 var viddata = $("input[name='panovideo']:checked").val();
2089
2090 if (viddata == 'on') {
2091
2092 $("li.scene").removeClass('active');
2093 $(".rex-pano-tab.wpvr_scene").removeClass('active');
2094 $("li.videos").addClass('active');
2095 $(".rex-pano-tab.video").addClass('active');
2096 $(".video-setting").show();
2097 $("li.general").hide();
2098 $("li.scene").hide();
2099 $("li.hotspot").hide();
2100 } else {
2101 // $(".video-setting").hide();
2102 $("li.general").show();
2103 $("li.scene").show();
2104 $("li.hotspot").show();
2105 }
2106 });
2107
2108 $(document).on("change", "select[name*=hotspot-customclass-pro]", function (event) {
2109 var getval = $(this).val();
2110 $(this).parent('.hotspot-setting').children('span.change-icon').html('<i class="' + getval + '"></i>');
2111
2112 });
2113
2114 $(document).on("change", ".hotspot-customclass-color", function (event) {
2115 var getcolor = $(this).val();
2116 color = getcolor;
2117 $('.hotspot-customclass-color-icon-value').val(getcolor);
2118 $('.hotspot-customclass-color').val(getcolor);
2119 });
2120
2121 jQuery(document).ready(function ($) {
2122 if ($(".icon-found-value")[0]) {
2123 color = $('.hotspot-customclass-color-icon-value.icon-found-value').val();
2124 } else {
2125 color = '#00b4ff';
2126 }
2127 });
2128
2129 function changeicon() {
2130 $('.hotspot-customclass-color-icon-value').val(color);
2131 $('.hotspot-customclass-color').val(color);
2132 }
2133
2134 //------------panolens tab js------------------
2135
2136
2137 $(document).on("click", ".scene-nav ul li:not(:last-child) span", function () {
2138
2139 var scene_id = $(this).data('index');
2140 scene_id = '#scene-' + scene_id;
2141
2142 j = $(scene_id).find('.hotspot-nav li').eq(-2).find('span').attr('data-index');
2143
2144 $([$(this).parent()[0], $($(this).data('href'))[0]]).addClass('active').siblings('.active').removeClass('active');
2145 $('#wpvr_active_scenes').val($(this).data('index'));
2146 });
2147
2148 //add click
2149 $(document).on("click", ".scene-nav ul li:last-child span", function () {
2150 var scene_id = $(this).parent('li').prev().children("span").data('index');
2151 scene_id = '#scene-' + scene_id;
2152 $(scene_id).removeAttr("style");
2153 j = $(scene_id).find('.hotspot-nav li').eq(-2).find('span').attr('data-index');
2154 $('.scene-nav ul li.active').removeClass('active');
2155 $(this).parent('li').prev().addClass('active');
2156 var sceneinfo = $('.scene-setup').repeaterVal();
2157 var infodata = sceneinfo['scene-list'];
2158 $('.hotspotscene').find('option').remove();
2159 $('.hotspotscene').append("<option value='none'>None</option>");
2160 for (var i in infodata) {
2161 var optiondata = infodata[i]['scene-id'];
2162 if (optiondata != '') {
2163 $('.hotspotscene').append("<option value='" + optiondata + "'>" + optiondata + "</option>");
2164 }
2165 }
2166 $('.hotspot-customclass-pro-select').fontIconPicker();
2167 $('span.change-icon').hide();
2168 });
2169
2170 //end add click
2171 $(document).on("click", ".hotspot-nav ul li:not(:last-child) span", function () {
2172 $('#wpvr_active_hotspot').val($(this).data('index'));
2173 $([$(this).parent()[0], $($(this).data('href'))[0]]).addClass('active').siblings('.active').removeClass('active');
2174 });
2175
2176 $(document).on("click", ".hotspot-nav ul li:last-child span", function () {
2177 $(this).parent('li').siblings('.active').removeClass('active');
2178 $(this).parent('li').prev().addClass('active');
2179 var sceneinfo = $('.scene-setup').repeaterVal();
2180 var infodata = sceneinfo['scene-list'];
2181 $('.hotspotscene').find('option').remove();
2182 $('.hotspotscene').append("<option value='none'>None</option>");
2183 for (var i in infodata) {
2184 var optiondata = infodata[i]['scene-id'];
2185 if (optiondata != '') {
2186 $('.hotspotscene').append("<option value='" + optiondata + "'>" + optiondata + "</option>");
2187 }
2188 }
2189 $('.trtr').trigger('change');
2190 $('.hotspot-customclass-pro-select').fontIconPicker();
2191 $('span.change-icon').hide();
2192
2193 });
2194
2195 function changehotspotid(id) {
2196 var scene_id = '#scene-' + id;
2197 var hotspot_id = 'scene-' + id + '-hotspot-1';
2198 $(scene_id).find('.hotspot-nav li span').attr('data-href', '#' + hotspot_id + '');
2199 $(scene_id).find('.single-hotspot').attr('id', hotspot_id);
2200
2201 }
2202
2203 $(document).on("click", ".rex-pano-nav-menu.main-nav ul li span", function () {
2204 var screen = $(this).parent().attr('data-screen');
2205
2206 var url_info = wpvr_global_obj.url_info
2207 if ( 'add' == url_info.screen ){
2208 var newUrl = url_info.admin_url+"post-new.php?"+"post_type="+url_info.param.post_type+"&active_tab="+screen;
2209 }else{
2210 var newUrl = url_info.admin_url+"post.php?"+"post="+url_info.param.post+"&action=edit"+"&active_tab="+screen;
2211 }
2212
2213 handle_add_pitch_button(screen);
2214 toggleSceneGallery(screen);
2215
2216 if (window.history != 'undefined' && window.history.pushState != 'undefined') {
2217 window.history.pushState({ path: newUrl }, '', newUrl);
2218 }
2219
2220 $('#wpvr_active_tab').val(screen);
2221 if ('hotspot' == screen) {
2222 $('.active_scene_id').show();
2223 var id = $('.single-scene.active').attr('id');
2224 $('.active_scene_id p').text(`${window.wpvr_localize.AddingHotspotsOnScene}`);
2225 var scenceID = $('#' + id + ' .sceneid').val();
2226 var span = '<span>(' + scenceID + ')</span>'
2227 $('.active_scene_id p').append(span);
2228 $('.active_scene_id').css({ "background-color": "#E0E1F7", "width": "100%", "text-align": "center", "padding": "10px 15px" });
2229 $('.active_scene_id p').css({ "color": "black", "font-size": "15px" });
2230 $('.active_scene_id p span').css({ "color": "#004efa", "font-size": "15px" });
2231
2232 } else {
2233 $('.active_scene_id').hide();
2234 }
2235 $([$(this).parent()[0], $($(this).data('href'))[0]]).addClass('active').siblings('.active').removeClass('active');
2236 });
2237
2238 //-Get Started reloaded -//
2239 $(document).on("click",".tabs.rex-tabs li a",function(){
2240 var tab = $(this).attr('href');
2241 var url = window.location;
2242 var origin = url.origin;
2243 var pathname = url.pathname
2244 var search_perameter = window.location.search.split('&');
2245 var makeUrl = origin + pathname + search_perameter[0]
2246 var newUrl = makeUrl + tab;
2247
2248 if (window.history != 'undefined' && window.history.pushState != 'undefined') {
2249 window.history.pushState({ path: newUrl }, '', newUrl);
2250 }
2251 })
2252 //----------alert dismiss--------//
2253 $(document).on("click", "body", function () {
2254 $('body').removeClass('error-overlay2');
2255 $('.pano-alert').removeClass('pano-default-warning').hide();
2256 });
2257 $(document).on("click", ".pano-alert .pano-error-close-btn", function () {
2258 $('body').removeClass('error-overlay2');
2259 $('.pano-alert').removeClass('pano-default-warning').hide();
2260 });
2261 $(document).on("click", ".pano-alert, .rex-pano-sub-tabs .rex-pano-tab-nav li.add", function (e) {
2262 e.stopPropagation();
2263 });
2264
2265
2266 $(document).on("click", ".main-nav li.hotspot span", function () {
2267 $(".hotspot-setup.rex-pano-sub-tabs").show();
2268 $(".scene-setup > nav.scene-nav").hide();
2269 $(".scene-setup .single-scene > .scene-content").hide();
2270 $(".scene-setup .delete-scene").hide();
2271 });
2272
2273 $(document).on("click", ".main-nav li.scene span", function () {
2274 $(".hotspot-setup.rex-pano-sub-tabs").hide();
2275 $(".scene-setup > nav.scene-nav").show();
2276 $(".scene-setup .single-scene > .scene-content").show();
2277 $(".scene-setup .delete-scene").show();
2278 });
2279
2280 $(document).on("change", ".dscen", function () {
2281 var dscene = $(this).val();
2282 if('on' === dscene){
2283 $('#wpvr-check-default').prop('checked', true);
2284 $('#wpvr-check-default').closest('.wpvr-checklist-item').css('color', '#0E003C');
2285 }else{
2286 $('#wpvr-check-default').prop('checked', false);
2287 $('#wpvr-check-default').closest('.wpvr-checklist-item').css('color', '#73707D');
2288 }
2289 updateProgress()
2290 $(".dscen").not(this).each(function () {
2291 var oth_scene = $(this).val();
2292 if (dscene == 'on' && oth_scene == 'on') {
2293 $('#error_occured').show();
2294 $('#error_occured .pano-error-message').html('<span class="pano-error-title">Default scene has been updated</span>');
2295 $('body').addClass('error-overlay');
2296 $('html, body').animate({
2297 scrollTop: $("#error_occured").offset().top
2298 }, 500);
2299 $(this).val('off');
2300
2301 }
2302 });
2303 });
2304
2305 $(document).on("change", ".sceneid", function () {
2306 var sceneinfo = $('.scene-setup').repeaterVal();
2307 var infodata = sceneinfo['scene-list'];
2308 $('.hotspotscene').find('option').remove();
2309 $('.hotspotscene').append("<option value='none'>None</option>");
2310 for (var i in infodata) {
2311 var optiondata = infodata[i]['scene-id'];
2312 if (optiondata != '') {
2313 $('.hotspotscene').append("<option value='" + optiondata + "'>" + optiondata + "</option>");
2314 }
2315 }
2316 });
2317
2318
2319
2320 function deleteinfodata() {
2321 var sceneinfo = $('.scene-setup').repeaterVal();
2322 var infodata = sceneinfo['scene-list'];
2323 $('.hotspotscene').find('option').remove();
2324 $('.hotspotscene').append("<option value='none'>None</option>");
2325 for (var i in infodata) {
2326 var optiondata = infodata[i]['scene-id'];
2327 if (optiondata != '') {
2328 $('.hotspotscene').append("<option value='" + optiondata + "'>" + optiondata + "</option>");
2329 }
2330 }
2331 }
2332
2333 $(document).on("change", ".hotspotscene", function () {
2334
2335 var chanheghtptpval = $(this).val();
2336 if (chanheghtptpval != "none") {
2337 $(this).parent('.hotspot-scene').siblings('.hotspot-scene').children('.hotspotsceneinfodata').val(chanheghtptpval);
2338 } else {
2339 $(this).parent('.hotspot-scene').siblings('.hotspot-scene').children('.hotspotsceneinfodata').val('');
2340 }
2341 });
2342
2343 $(document).on("click", ".hotpitch", function (event) {
2344 var datacoords = $('#panodata').text().split(',');
2345 var pitchsplit = datacoords[0];
2346 var pitch = pitchsplit.split(':');
2347 $(this).parent().parent('.hotspot-setting').children('.hotspot-pitch').val(pitch[1].trim());
2348 });
2349
2350 $(document).on("click", ".hotyaw", function (event) {
2351 var datacoords = $('#panodata').text().split(',');
2352 var yawsplit = datacoords[1];
2353 var yaw = yawsplit.split(':');
2354 $(this).parent().parent('.hotspot-setting').children('.hotspot-yaw').val(yaw[1].trim());
2355 });
2356
2357 jQuery(document).ready(function ($) {
2358
2359 if ($(".scene-setup").length > 0) {
2360 var sceneinfo = $('.scene-setup').repeaterVal();
2361 var infodata = sceneinfo['scene-list'];
2362 $('.hotspotscene').find('option').remove();
2363 $('.hotspotscene').append("<option value='none'>None</option>");
2364 for (var i in infodata) {
2365 var optiondata = infodata[i]['scene-id'];
2366 if (optiondata != '') {
2367 $('.hotspotscene').append("<option value='" + optiondata + "'>" + optiondata + "</option>");
2368 }
2369 }
2370 }
2371 });
2372
2373 $(document).on("click", ".toppitch", function (event) {
2374 var datacoords = $('#panodata').text().split(',');
2375 var pitchsplit = datacoords[0];
2376 var pitch = pitchsplit.split(':');
2377 var yawsplit = datacoords[1];
2378 var yaw = yawsplit.split(':');
2379
2380 $('div.single-scene.rex-pano-tab.active').children('div.hotspot-setup.rex-pano-sub-tabs').children('div.rex-pano-tab-content').children('div.single-hotspot.rex-pano-tab.active.clearfix').find('.hotspot-pitch').val(pitch[1].trim());
2381 $('div.single-scene.rex-pano-tab.active').children('div.hotspot-setup.rex-pano-sub-tabs').children('div.rex-pano-tab-content').children('div.single-hotspot.rex-pano-tab.active.clearfix').find('.hotspot-yaw').val(yaw[1].trim());
2382 });
2383 jQuery(document).ready(function ($) {
2384 $('.hotspot-customclass-pro-select').fontIconPicker();
2385 });
2386 jQuery(document).ready(function ($) {
2387 $('span.change-icon').hide();
2388 });
2389
2390 jQuery(document).ready(function ($) {
2391 var autrotateset = $("input[name='autorotation']").is(':checked') ? 'on' : 'off';
2392 if (autrotateset == 'off') {
2393 $('.autorotationdata-wrapper').hide();
2394 $('.autorotationdata-wrapper input').prop('disabled', true);
2395 } else {
2396 $('.autorotationdata-wrapper').show();
2397 $('.autorotationdata-wrapper input').prop('disabled', false);
2398 }
2399
2400
2401 });
2402
2403 $(document).on("change", "input[name='autorotation']", function (event) {
2404 var autrotateset = $(this).is(':checked') ? 'on' : 'off';
2405
2406 if (autrotateset == 'on') {
2407 $('.autorotationdata-wrapper').show();
2408 $('.autorotationdata-wrapper input').prop('disabled', false);
2409 } else {
2410 $('.autorotationdata-wrapper').hide();
2411 $('.autorotationdata-wrapper input').prop('disabled', true);
2412 }
2413 });
2414
2415
2416 $(document).on("change", ".ptyscene", function (event) {
2417 var ptyscene = $(this).val();
2418 if (ptyscene == 'off') {
2419 $(this).parent('.single-settings').siblings('.ptyscenedata').hide();
2420 } else {
2421 $(this).parent('.single-settings').siblings('.ptyscenedata').show();
2422 }
2423 });
2424
2425 $(document).on("change", ".cvgscene", function (event) {
2426 var cvgscene = $(this).val();
2427 if (cvgscene == 'off') {
2428 $(this).parent('.single-settings').siblings('.cvgscenedata').hide();
2429 } else {
2430 $(this).parent('.single-settings').siblings('.cvgscenedata').show();
2431 }
2432 });
2433
2434 $(document).on("change", ".chgscene", function (event) {
2435 var chgscenedata = $(this).val();
2436 if (chgscenedata == 'off') {
2437 $(this).parent('.single-settings').siblings('.chgscenedata').hide();
2438 } else {
2439 $(this).parent('.single-settings').siblings('.chgscenedata').show();
2440 }
2441 });
2442
2443 $(document).on("change", ".czscene", function (event) {
2444 var czscene = $(this).val();
2445 if (czscene == 'off') {
2446 $(this).parent('.single-settings').siblings('.czscenedata').hide();
2447 } else {
2448 $(this).parent('.single-settings').siblings('.czscenedata').show();
2449 }
2450 });
2451
2452 /**
2453 * Nasim
2454 * enable script button on chnage action
2455 */
2456 $("#wpvr_script_control").change(function () {
2457
2458 if ($('#wpvr_script_control').is(':checked')) {
2459
2460 $(".wpvr_enqueue_script_list").show();
2461
2462 } else {
2463
2464 $(".wpvr_enqueue_script_list").hide();
2465 }
2466
2467 });
2468
2469 /**
2470 * Sakib
2471 * enable script button on chnage action
2472 */
2473 $("#wpvr_video_script_control").change(function () {
2474
2475 if ($('#wpvr_video_script_control').is(':checked')) {
2476
2477 $(".wpvr_enqueue_video_script_list").show();
2478
2479 } else {
2480
2481 $(".wpvr_enqueue_video_script_list").hide();
2482 }
2483
2484 });
2485
2486
2487 /**
2488 * Nasim
2489 * Check enable script button is on or not
2490 * if on then script list field will be show and if off then script list field will be hide
2491 */
2492 if ($('#wpvr_script_control').is(':checked')) {
2493
2494 $(".wpvr_enqueue_script_list").show();
2495
2496 } else {
2497
2498 $(".wpvr_enqueue_script_list").hide();
2499 }
2500
2501 /**
2502 * Sakib
2503 * Check enable script button is on or not
2504 * if on then script list field will be show and if off then script list field will be hide
2505 */
2506 if ($('#wpvr_video_script_control').is(':checked')) {
2507
2508 $(".wpvr_enqueue_video_script_list").show();
2509
2510 } else {
2511
2512 $(".wpvr_enqueue_video_script_list").hide();
2513 }
2514
2515 /**
2516 * Hides the alert in the settings footer area after a 2000ms delay.
2517 *
2518 * @return {void} No return value
2519 */
2520 function remove_alert(){
2521 setTimeout(function(){
2522 $('.settings-footer-area .wpvr-alert').hide();
2523 }, 2000);
2524 }
2525
2526 $(document).on("click", "#wpvr_role_submit", function (e) {
2527 e.preventDefault();
2528 var ajaxurl = wpvr_obj.ajaxurl;
2529 $(this).children().css('display', 'inline-block');
2530
2531 $('#wpvr_role_submit').attr('disabled', true);
2532 var editor = $('#wpvr_editor_active').is(':checked');
2533 var author = $('#wpvr_author_active').is(':checked');
2534 var fontawesome = $('#wpvr_fontawesome_disable').is(':checked');
2535 var mobile_media_resize = $('#mobile_media_resize').is(':checked');
2536 var wpvr_frontend_notice = $('#wpvr_frontend_notice').is(':checked');
2537 var wpvr_frontend_notice_area = $('#wpvr_frontend_notice_area').val();
2538 var wpvr_script_control = $('#wpvr_script_control').is(':checked');
2539 var wpvr_script_list = $('#wpvr_script_list').val();
2540 var wpvr_video_script_control = $('#wpvr_video_script_control').is(':checked');
2541 var wpvr_video_script_list = $('#wpvr_video_script_list').val();
2542 var high_res_image = $('#high_res_image').is(':checked');
2543 var dis_on_hover = $('#dis_on_hover').is(':checked');
2544 var wpvr_mobile_hotspot_tip = $('#wpvr_mobile_hotspot_tip').is(':checked');
2545 var dokan_vendor = $('#wpvr_dokan_vendor_active').is(':checked');
2546 var wpvr_usage_tracking = $('#wpvr_usage_tracking').is(':checked');
2547
2548 /**
2549 * check enable script button is on and script list field is not empty
2550 */
2551 if ( ($('#wpvr_video_script_control').is(':checked') && wpvr_video_script_list == '') || ($('#wpvr_script_control').is(':checked') && wpvr_script_list == '') ) {
2552 if(($('#wpvr_script_control').is(':checked') && wpvr_script_list == '')){
2553 if (confirm('The "List of Allowed Pages To Load WP VR Scripts " Field Is Empty. No Virtual Tours Will Show Up on Your Site.')) {
2554 if($('#wpvr_video_script_control').is(':checked') && wpvr_video_script_list == ''){
2555 if (confirm("The 'List of Allowed Pages To Load WPVR Video.js ' Field Is Empty. Any Self-hosted 360-degree videos won't function on your site.")) {
2556 jQuery.ajax({
2557 type: "POST",
2558 url: ajaxurl,
2559 data: {
2560 action: "wpvr_role_management",
2561 nonce : wpvr_obj.ajax_nonce,
2562 editor: editor,
2563 author: author,
2564 fontawesome: fontawesome,
2565 mobile_media_resize: mobile_media_resize,
2566 high_res_image: high_res_image,
2567 dis_on_hover: dis_on_hover,
2568 wpvr_mobile_hotspot_tip: wpvr_mobile_hotspot_tip,
2569 wpvr_frontend_notice: wpvr_frontend_notice,
2570 wpvr_frontend_notice_area: wpvr_frontend_notice_area,
2571 wpvr_script_control: wpvr_script_control,
2572 wpvr_script_list: wpvr_script_list,
2573 wpvr_video_script_control: wpvr_video_script_control,
2574 wpvr_video_script_list: wpvr_video_script_list,
2575 dokan_vendor: dokan_vendor,
2576 wpvr_usage_tracking: wpvr_usage_tracking,
2577 // woocommerce: woocommerce,
2578 },
2579 success: function (response) {
2580 $('#wpvr_role_submit .wpvr-loader').css('display', 'none');
2581 $('#wpvr_role_submit').attr('disabled', false);
2582
2583 if (response.status == 'success') {
2584 $('.settings-footer-area .wpvr-alert').text(response.message).show();
2585 }
2586
2587 remove_alert();
2588
2589 }
2590 });
2591 } else {
2592 $('#wpvr_role_submit .wpvr-loader').css('display', 'none');
2593 $('#wpvr_role_submit').attr('disabled', false);
2594 }
2595 }else{
2596 jQuery.ajax({
2597 type: "POST",
2598 url: ajaxurl,
2599 data: {
2600 action: "wpvr_role_management",
2601 nonce : wpvr_obj.ajax_nonce,
2602 editor: editor,
2603 author: author,
2604 fontawesome: fontawesome,
2605 mobile_media_resize: mobile_media_resize,
2606 high_res_image: high_res_image,
2607 wpvr_frontend_notice: wpvr_frontend_notice,
2608 wpvr_frontend_notice_area: wpvr_frontend_notice_area,
2609 wpvr_script_control: wpvr_script_control,
2610 wpvr_script_list: wpvr_script_list,
2611 wpvr_video_script_control: wpvr_video_script_control,
2612 wpvr_video_script_list: wpvr_video_script_list,
2613 dokan_vendor: dokan_vendor,
2614 wpvr_usage_tracking: wpvr_usage_tracking,
2615 // woocommerce: woocommerce,
2616 },
2617 success: function (response) {
2618 $('#wpvr_role_submit .wpvr-loader').css('display', 'none');
2619 $('#wpvr_role_submit').attr('disabled', false);
2620
2621 if (response.status == 'success') {
2622 $('.settings-footer-area .wpvr-alert').text(response.message).show();
2623 }
2624
2625 remove_alert();
2626
2627 }
2628 });
2629 }
2630 } else {
2631 $('#wpvr_role_submit .wpvr-loader').css('display', 'none');
2632 $('#wpvr_role_submit').attr('disabled', false);
2633 }
2634 }else if($('#wpvr_video_script_control').is(':checked') && wpvr_video_script_list == ''){
2635
2636 if (confirm("The 'List of Allowed Pages To Load WPVR Video.js ' Field Is Empty. Any Self-hosted 360-degree videos won't function on your site.")) {
2637 if(($('#wpvr_script_control').is(':checked') && wpvr_script_list == '')){
2638 if (confirm('The "List of Allowed Pages To Load WP VR Scripts " Field Is Empty. No Virtual Tours Will Show Up on Your Site.')) {
2639 jQuery.ajax({
2640 type: "POST",
2641 url: ajaxurl,
2642 data: {
2643 action: "wpvr_role_management",
2644 nonce : wpvr_obj.ajax_nonce,
2645 editor: editor,
2646 author: author,
2647 fontawesome: fontawesome,
2648 mobile_media_resize: mobile_media_resize,
2649 high_res_image: high_res_image,
2650 dis_on_hover: dis_on_hover,
2651 wpvr_mobile_hotspot_tip: wpvr_mobile_hotspot_tip,
2652 wpvr_frontend_notice: wpvr_frontend_notice,
2653 wpvr_frontend_notice_area: wpvr_frontend_notice_area,
2654 wpvr_script_control: wpvr_script_control,
2655 wpvr_script_list: wpvr_script_list,
2656 wpvr_video_script_control: wpvr_video_script_control,
2657 wpvr_video_script_list: wpvr_video_script_list,
2658 dokan_vendor: dokan_vendor,
2659 wpvr_usage_tracking: wpvr_usage_tracking,
2660 // woocommerce: woocommerce,
2661 },
2662 success: function (response) {
2663 $('#wpvr_role_submit .wpvr-loader').css('display', 'none');
2664 $('#wpvr_role_submit').attr('disabled', false);
2665
2666 if (response.status == 'success') {
2667 $('.settings-footer-area .wpvr-alert').text(response.message).show();
2668 }
2669 remove_alert();
2670
2671 }
2672 });
2673 }else {
2674 $('#wpvr_role_submit .wpvr-loader').css('display', 'none');
2675 $('#wpvr_role_submit').attr('disabled', false);
2676 }
2677 }else{
2678 jQuery.ajax({
2679 type: "POST",
2680 url: ajaxurl,
2681 data: {
2682 action: "wpvr_role_management",
2683 nonce : wpvr_obj.ajax_nonce,
2684 editor: editor,
2685 author: author,
2686 fontawesome: fontawesome,
2687 mobile_media_resize: mobile_media_resize,
2688 high_res_image: high_res_image,
2689 dis_on_hover: dis_on_hover,
2690 wpvr_mobile_hotspot_tip: wpvr_mobile_hotspot_tip,
2691 wpvr_frontend_notice: wpvr_frontend_notice,
2692 wpvr_frontend_notice_area: wpvr_frontend_notice_area,
2693 wpvr_script_control: wpvr_script_control,
2694 wpvr_script_list: wpvr_script_list,
2695 wpvr_video_script_control: wpvr_video_script_control,
2696 wpvr_video_script_list: wpvr_video_script_list,
2697 dokan_vendor: dokan_vendor,
2698 wpvr_usage_tracking: wpvr_usage_tracking,
2699 // woocommerce: woocommerce,
2700 },
2701 success: function (response) {
2702 $('#wpvr_role_submit .wpvr-loader').css('display', 'none');
2703 $('#wpvr_role_submit').attr('disabled', false);
2704
2705 if (response.status == 'success') {
2706 $('.settings-footer-area .wpvr-alert').text(response.message).show();
2707 }
2708
2709 remove_alert();
2710
2711 }
2712 });
2713 }
2714 } else {
2715 $('#wpvr_role_submit .wpvr-loader').css('display', 'none');
2716 $('#wpvr_role_submit').attr('disabled', false);
2717 }
2718 }
2719
2720 } else {
2721 jQuery.ajax({
2722 type: "POST",
2723 url: ajaxurl,
2724 data: {
2725 action: "wpvr_role_management",
2726 nonce : wpvr_obj.ajax_nonce,
2727 editor: editor,
2728 author: author,
2729 fontawesome: fontawesome,
2730 mobile_media_resize: mobile_media_resize,
2731 high_res_image: high_res_image,
2732 dis_on_hover: dis_on_hover,
2733 wpvr_mobile_hotspot_tip: wpvr_mobile_hotspot_tip,
2734 wpvr_frontend_notice: wpvr_frontend_notice,
2735 wpvr_frontend_notice_area: wpvr_frontend_notice_area,
2736 wpvr_script_control: wpvr_script_control,
2737 wpvr_script_list: wpvr_script_list,
2738 wpvr_video_script_control: wpvr_video_script_control,
2739 wpvr_video_script_list: wpvr_video_script_list,
2740 dokan_vendor: dokan_vendor,
2741 wpvr_usage_tracking: wpvr_usage_tracking,
2742 },
2743 success: function (response) {
2744 $('#wpvr_role_submit .wpvr-loader').css('display', 'none');
2745 $('#wpvr_role_submit').attr('disabled', false);
2746 if (response.status == 'success') {
2747 $('.settings-footer-area .wpvr-alert').text(response.message).show();
2748 }
2749
2750 remove_alert();
2751 }
2752 });
2753 }
2754
2755
2756
2757 });
2758
2759
2760 //-----------reset button----------
2761 $(document).on("click", "#wpvr_role_reset", function (e) {
2762 e.preventDefault();
2763 $(this).attr('disabled', true);
2764
2765 var confirmation = confirm('All settings will be reset to default. Are you sure?');
2766 // Code to reset settings to default if the user clicks "Yes"
2767 if (confirmation) {
2768 $('#wpvr_editor_active').prop('checked', false);
2769 $('#wpvr_author_active').prop('checked', false);
2770 $('#wpvr_fontawesome_disable').prop('checked', false);
2771 $('#mobile_media_resize').prop('checked', false);
2772 $('#wpvr_frontend_notice').prop('checked', false);
2773 $('#wpvr_script_control').prop('checked', false);
2774 $('#wpvr_video_script_control').prop('checked', false);
2775 $('#high_res_image').prop('checked', false);
2776 $('#dis_on_hover').prop('checked', false);
2777 $('#wpvr_mobile_hotspot_tip').prop('checked', false);
2778 $('#wpvr_dokan_vendor_active').prop('checked', false);
2779 $('#wpvr_usage_tracking').prop('checked', false);
2780 $(".wpvr_enqueue_video_script_list").hide();
2781 $(".wpvr_enqueue_script_list").hide();
2782
2783 $("#wpvr_role_submit").trigger('click');
2784 }
2785 $(this).attr('disabled', false);
2786
2787 });
2788
2789 //------general tab's inner tab-------
2790 jQuery(document).ready(function ($) {
2791
2792 $('.general-inner-tab .inner-nav li span').on('click', function () {
2793 var this_id = $(this).attr('data-href');
2794
2795 $(this).parent('li').addClass('active');
2796 $(this).parent('li').siblings().removeClass('active');
2797
2798 $(this_id).show();
2799 $(this_id).siblings().hide();
2800 });
2801 });
2802
2803 //------active tab scripts-------
2804 jQuery(document).ready(function ($) {
2805
2806 function getUrlVars() {
2807 var vars = [],
2808 hash;
2809 var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
2810 for (var i = 0; i < hashes.length; i++) {
2811 hash = hashes[i].split('=');
2812 vars.push(hash[0]);
2813 vars[hash[0]] = hash[1];
2814 }
2815 return vars;
2816 }
2817 var activeTab = 'general',
2818 vr_main_tab = $('#wpvr-main-nav'),
2819 var_main_tab_contents = $('#wpvr-main-tab-contents').find('.rex-pano-tab').not(".single-scene,.single-hotspot"),
2820 scene_content = $('.scene-content'),
2821 scene_nav = $('.scene-nav'),
2822 single_scene = $('.single-scene'),
2823 hotspot_content = $('.hotspot-setup'),
2824 single_hotspot = $('.single-hotspot'),
2825 delete_scene_btn = $('.delete-scene'),
2826 delete_hotspot_btn = $('.delete-hotspot');
2827
2828 var _q_activeTab = getUrlVars()["active_tab"];
2829 var _sceneID = getUrlVars()["scene"];
2830 var _hotspotID = getUrlVars()["hotspot"];
2831 var default_tabs = ['general', 'scene', 'hotspot', 'video'];
2832 if (_q_activeTab) {
2833 if (default_tabs.includes(_q_activeTab)) {
2834 activeTab = _q_activeTab;
2835 if(activeTab == "video" ){
2836 vr_main_tab.find('li:not(:first)').removeClass('active');
2837 vr_main_tab.find(".videos").addClass('active');
2838 }else{
2839 vr_main_tab.find('li:not(:first)').removeClass('active');
2840 vr_main_tab.find('.' + activeTab).addClass('active');
2841 }
2842
2843 // scene screens
2844 var_main_tab_contents.addClass('active');
2845 if (activeTab === 'scene' || activeTab === 'hotspot') {
2846 var_main_tab_contents.not('#scenes').removeClass('active');
2847 } else {
2848 var_main_tab_contents.not('#' + activeTab).removeClass('active');
2849 }
2850 if(activeTab === 'hotspot'){
2851 $(".rex-pano-nav-menu.main-nav ul li.hotspot span").trigger('click')
2852 }
2853
2854 // scene contents
2855 if (_sceneID) {
2856 var scenesIds = [];
2857 var sceneID = '#scene-' + _sceneID;
2858 var scene_nav_items = scene_nav.find('li');
2859 scene_nav.find('li').each(function () {
2860 var index = $(this).find('span').attr('data-index');
2861 if (index) {
2862 scenesIds.push(index);
2863 }
2864 });
2865 if (scenesIds.includes(_sceneID)) {
2866 scene_nav_items.removeClass('active');
2867 scene_nav.find('li').each(function () {
2868 var index = $(this).find('span').attr('data-index');
2869 if (_sceneID == index) {
2870 $(this).addClass('active');
2871 }
2872 });
2873 if (activeTab == 'scene' || _sceneID) {
2874 single_scene.removeClass('active');
2875 $(sceneID).addClass('active');
2876 }
2877 } else {
2878 scene_nav.find('li:first').addClass('active');
2879 }
2880
2881 if (activeTab === 'scene') {
2882 if (scenesIds.includes(_sceneID)) {
2883 $(single_scene).removeClass('active');
2884 $(sceneID).addClass('active');
2885 }
2886 } else {
2887 $(delete_scene_btn).hide();
2888 $(scene_nav).hide();
2889 $('.scene-content').hide();
2890 $(sceneID).find('.hotspot-setup').show();
2891 }
2892
2893 //hotspot contents
2894 var hotspot_nav = $('.single-scene.active').find('.hotspot-nav');
2895 var hotspotIds = [];
2896 var hotspot_nav_items = $('.single-scene.active').find('.hotspot-nav').find('li');
2897 var activeHotspotId = '#scene-' + _sceneID + 'hotspot-' + _hotspotID;
2898 hotspot_nav_items.each(function () {
2899 var index = $(this).find('span').attr('data-index');
2900 if (index) {
2901 hotspotIds.push(index);
2902 activeHotspotId = $(this).find('span').attr('data-href');
2903 }
2904 });
2905 if (hotspotIds.includes(_hotspotID)) {
2906 hotspot_nav_items.removeClass('active');
2907 hotspot_nav.find('li').each(function () {
2908 var index = $(this).find('span').attr('data-index');
2909 if (_hotspotID === index) {
2910 $(this).addClass('active');
2911 }
2912 });
2913 if (activeHotspotId) {
2914 $(sceneID).find('.single-hotspot').removeClass('active');
2915 $(activeHotspotId).addClass('active');
2916 }
2917 }
2918 }
2919 }
2920 }
2921
2922
2923 $(document).on("click", ".wpvr-help-resource__video-section", function () {
2924 $('#wpvr-help-video-iframe').attr('src', 'https://www.youtube.com/embed/kKHUlVKtesQ');
2925 if($('#wpvr-help-video-iframe').attr('src') != ''){
2926 $(".wpvr-iframe-modal").show();
2927 }
2928 });
2929
2930
2931 $(document).on("click", ".wpvr-iframe-modal__cross-icon", function () {
2932 $(".wpvr-iframe-modal").hide();
2933 var videoPlayer =$('#wpvr-help-video-iframe');
2934 videoPlayer.attr('src', '');
2935
2936 });
2937
2938
2939
2940 });
2941
2942 $(document).on("click", ".wpvr_url_open", function (event) {
2943 if ($(this).val() == 'off') {
2944 $(this).val('on');
2945 }
2946 else {
2947 $(this).val('off');
2948 }
2949 });
2950
2951 $(document).ready(function() {
2952 $('textarea[name*=hotspot-content]').summernote({
2953 toolbar: [
2954 ['style', ['style']],
2955 ['font', ['bold', 'underline', 'clear']],
2956 ['fontname', ['fontname']],
2957 ['color', ['color']],
2958 ['para', ['ul', 'ol', 'paragraph']],
2959 ['table', ['table']],
2960 ['insert', ['link', 'picture', 'video']],
2961 ['view', ['codeview', 'help']],
2962 ],
2963 callbacks: {
2964 onInit: function() {
2965 var $editor = $(this);
2966 var $noteEditor = $editor.next('.note-editor');
2967
2968 // Intercept Video button click
2969 $noteEditor.on('click', 'button.note-btn[aria-label="Video"]', function(e) {
2970 // Small delay to check if cursor is on a video
2971 setTimeout(function() {
2972 // Get the current selection
2973 var range = $editor.summernote('createRange');
2974 if (range) {
2975 var $node = $(range.sc);
2976
2977 // Check if cursor is on a video iframe
2978 var $iframe = $node.closest('iframe.note-video-clip');
2979 if (!$iframe.length) {
2980 $iframe = $node.find('iframe.note-video-clip').first();
2981 }
2982
2983 if ($iframe.length && $iframe.attr('src')) {
2984 var embedUrl = $iframe.attr('src');
2985 var videoUrl = '';
2986
2987 // Extract YouTube URL
2988 if (embedUrl && (embedUrl.indexOf('youtube.com') > -1 || embedUrl.indexOf('youtu.be') > -1)) {
2989 var match = embedUrl.match(/embed\/([^?&]*)/);
2990 if (match && match[1]) {
2991 videoUrl = 'https://www.youtube.com/watch?v=' + match[1];
2992 }
2993 } else if (embedUrl) {
2994 videoUrl = embedUrl;
2995 }
2996
2997 // Show the video dialog
2998 $editor.summernote('videoDialog.show');
2999
3000 // Pre-populate the video URL in the dialog
3001 setTimeout(function() {
3002 var $urlInput = $('.note-video-url');
3003 if ($urlInput.length && videoUrl) {
3004 $urlInput.val(videoUrl);
3005 $urlInput.focus();
3006 }
3007 }, 150);
3008 }
3009 }
3010 }, 50);
3011 });
3012 },
3013 onKeyup: function(e) {
3014 var getHotspotContent = $(this).summernote('code').trim();
3015 var tempDiv = document.createElement('div');
3016 tempDiv.innerHTML = getHotspotContent;
3017 var plainText = tempDiv.textContent || tempDiv.innerText || '';
3018 plainText = plainText.replace(/\u00a0/g, '').trim();
3019 var getParent = $(this).parent();
3020 var getMainParent = getParent.parent();
3021 var getClickContent = getMainParent.find('.hotspot-url');
3022
3023 if (plainText.length > 0) {
3024 getClickContent.find('input[name*=hotspot-url]').val('');
3025 getClickContent.find('input[name*=hotspot-url]').attr('placeholder', 'You can set either a URL or an On-click content');
3026 getClickContent.find('input[name*=hotspot-url]').attr("disabled", true);
3027 } else {
3028 getClickContent.find('input[name*=hotspot-url]').attr("disabled", false);
3029 }
3030 }
3031 }
3032 });
3033 $('textarea[name*=hotspot-hover]').summernote({
3034 toolbar: [
3035 ['style', ['style']],
3036 ['font', ['bold', 'underline', 'clear']],
3037 ['fontname', ['fontname']],
3038 ['color', ['color']],
3039 ['para', ['ul', 'ol', 'paragraph']],
3040 ['table', ['table']],
3041 ['insert', ['link', 'picture', 'video']],
3042 ['view', ['codeview', 'help']],
3043 ],
3044 fontNames: ['Arial', 'Helvetica', 'Tahoma', 'Courier New', 'Verdana', 'Impact', 'Times New Roman', 'system-ui', 'Helvetica Neue'],
3045 callbacks: {
3046 onInit: function() {
3047 var $editor = $(this);
3048 var $noteEditor = $editor.next('.note-editor');
3049
3050 // Intercept Video button click
3051 $noteEditor.on('click', 'button.note-btn[aria-label="Video"]', function(e) {
3052 // Small delay to check if cursor is on a video
3053 setTimeout(function() {
3054 // Get the current selection
3055 var range = $editor.summernote('createRange');
3056 if (range) {
3057 var $node = $(range.sc);
3058
3059 // Check if cursor is on a video iframe
3060 var $iframe = $node.closest('iframe.note-video-clip');
3061 if (!$iframe.length) {
3062 $iframe = $node.find('iframe.note-video-clip').first();
3063 }
3064
3065 if ($iframe.length && $iframe.attr('src')) {
3066 var embedUrl = $iframe.attr('src');
3067 var videoUrl = '';
3068
3069 // Extract YouTube URL
3070 if (embedUrl && (embedUrl.indexOf('youtube.com') > -1 || embedUrl.indexOf('youtu.be') > -1)) {
3071 var match = embedUrl.match(/embed\/([^?&]*)/);
3072 if (match && match[1]) {
3073 videoUrl = 'https://www.youtube.com/watch?v=' + match[1];
3074 }
3075 } else if (embedUrl) {
3076 videoUrl = embedUrl;
3077 }
3078
3079 // Show the video dialog
3080 $editor.summernote('videoDialog.show');
3081
3082 // Pre-populate the video URL in the dialog
3083 setTimeout(function() {
3084 var $urlInput = $('.note-video-url');
3085 if ($urlInput.length && videoUrl) {
3086 $urlInput.val(videoUrl);
3087 $urlInput.focus();
3088 }
3089 }, 150);
3090 }
3091 }
3092 }, 50);
3093 });
3094
3095 // Override font name dropdown click handler for this specific editor
3096 $editor.next('.note-editor').find('.dropdown-fontname a').off('click').on('click', function(e) {
3097 e.preventDefault();
3098 var fontName = $(this).data('value') || $(this).text();
3099
3100 // Focus on the current editor
3101 $editor.summernote('focus');
3102
3103 // Use Summernote's built-in method to apply font
3104 try {
3105 // First, clear any existing font formatting
3106 var range = $editor.summernote('createRange');
3107 if (range && !range.isCollapsed()) {
3108 // Get selected text
3109 var selectedText = range.toString();
3110
3111 // Use Summernote's insertHTML to replace content
3112 var fontHtml = '<span style="font-family: ' + fontName + ';">' + selectedText + '</span>';
3113 $editor.summernote('insertHTML', fontHtml);
3114 } else {
3115 // No selection, use execCommand for typing
3116 $editor.summernote('focus');
3117 document.execCommand('fontName', false, fontName);
3118 }
3119 } catch (error) {
3120 console.log('Font application error, using fallback method');
3121 // Fallback method
3122 document.execCommand('fontName', false, fontName);
3123 }
3124
3125 // Update dropdown button text for this editor
3126 $(this).closest('.note-editor').find('.note-current-fontname').text(fontName);
3127
3128 // Close dropdown
3129 var $dropdownMenu = $(this).closest('.dropdown-menu');
3130 $dropdownMenu.removeClass('show').hide();
3131 $dropdownMenu.prev('.dropdown-toggle').removeClass('show').attr('aria-expanded', 'false');
3132
3133 // Trigger change event
3134 setTimeout(function() {
3135 $editor.trigger('summernote.change');
3136 }, 100);
3137 });
3138 },
3139
3140 // Clean up the content after any change
3141 onChange: function(contents, $editable) {
3142 // Debounce the cleanup to avoid conflicts
3143 clearTimeout(this.cleanupTimeout);
3144 this.cleanupTimeout = setTimeout(function() {
3145 // Remove all font-family styles from elements that shouldn't have them
3146 $editable.find('*:not(span)').each(function() {
3147 if (this.style && this.style.fontFamily) {
3148 this.style.fontFamily = '';
3149 }
3150 });
3151
3152 // Clean up empty spans
3153 $editable.find('span').each(function() {
3154 var $span = $(this);
3155 var text = $span.text().replace(/[\uFEFF\u200B-\u200D\u2060]/g, '').trim();
3156
3157 if (!text) {
3158 $span.remove();
3159 } else {
3160 // If span has other styles besides font-family, keep only font-family
3161 var fontFamily = $span.css('font-family');
3162 if (fontFamily && fontFamily !== 'inherit') {
3163 $span.attr('style', 'font-family: ' + fontFamily + ';');
3164 } else if (!fontFamily || fontFamily === 'inherit') {
3165 $span.contents().unwrap();
3166 }
3167 }
3168 });
3169
3170 // Remove nested spans with font-family
3171 $editable.find('span[style*="font-family"] span[style*="font-family"]').each(function() {
3172 $(this).contents().unwrap();
3173 });
3174 }, 200);
3175 }
3176 }
3177 });
3178 });
3179
3180 $(document).on("submit", "#trigger-rollback", function (event) {
3181 event.preventDefault();
3182 if(confirm('Are you sure?')) {
3183 let version = $("#trigger-rollback").serialize();
3184 let redirectUrl = wpvr_global_obj.url_info.admin_url + 'admin.php?' + version;
3185 window.location.href = redirectUrl;
3186 }
3187 });
3188
3189 $(document).on("click", ".single-settings .wpvr-switcher input:disabled+label,.vr-export,#styled-radio-sv-off,#styled-radio-sv-on,#wpvr_floor_plan_enabler,.wpvr_cardboard_disable_label,.rex-import-disable,.single-settings.scene-animation", function (event) {
3190 event.preventDefault();
3191 $("#wpvr_premium_feature_popup").show();
3192 });
3193
3194
3195
3196 $(document).on("click", "#wpvr_premium_feature_close", function () {
3197 $("#wpvr_premium_feature_popup").hide();
3198 });
3199
3200
3201 $(document).on("click", ".wpvr-help-resource__dropdown-section", function () {
3202 // When an element with the class 'wpvr-help-resource__dropdown-section' is clicked,
3203 // toggle the 'show-dropdown' class on its siblings.
3204 $(this).siblings().toggleClass("show-dropdown");
3205 });
3206
3207 $(document).on("click", ".wpvr-layout__radio-container", function () {
3208 let findLayout = $(this).find('.wpvr-layout__radio-label').data('layout');
3209
3210 if(findLayout == 'layout1'){
3211 event.preventDefault();
3212
3213 $('#wpvr_premium_feature_popup').show();
3214 }
3215 });
3216
3217 // ------window on scroll add class to comparison table header------
3218 $(window).on('scroll', function() {
3219 var $header = $('.wpvr-compare .list-header');
3220
3221 if ($header.length > 0) {
3222 var headerOffset = $header.offset().top - $(window).scrollTop();
3223
3224 if (headerOffset < 27) {
3225 $header.addClass('sticked');
3226 } else {
3227 $header.removeClass('sticked');
3228 }
3229
3230 }
3231
3232 });
3233
3234 $(document).ready(function() {
3235 handle_add_pitch_button();
3236 });
3237
3238 $(document).on( 'mousedown', 'div.pnlm-dragfix', () => { handle_add_pitch_button() } );
3239
3240 function get_active_tab() {
3241 let activeTab = $('#wpvr_active_tab').val() ?? null;
3242 if ( !activeTab ) {
3243 activeTab = $(".rex-pano-tab-nav li.active").data('screen');
3244 }
3245 return activeTab;
3246 }
3247
3248 function handle_add_pitch_button( activeTab = null, panovideo = null ) {
3249 activeTab = activeTab === null ? get_active_tab() : activeTab;
3250
3251 if(handle_hotspot_tab(activeTab, true))
3252 return;
3253
3254 if( activeTab && 'hotspot' === activeTab && '' !== $( "#panodata" ).html().trim() ) {
3255 $(".add-pitch").removeClass('rex-hide-coordinates');
3256 }
3257 else {
3258 $(".add-pitch").addClass('rex-hide-coordinates');
3259 }
3260
3261 if('video' === activeTab){
3262 $(".rex-add-coordinates").addClass('rex-hide-coordinates');
3263 }else{
3264 $(".rex-add-coordinates").removeClass('rex-hide-coordinates');
3265 }
3266
3267 // Hide checklist for streetview tours in edit mode
3268 var isStreetViewTour = false;
3269 // Check by input (edit mode)
3270 if ($("input[name='wpvrStreetView']:checked").val() === 'on') {
3271 isStreetViewTour = true;
3272 }
3273 if( 'streetview' === activeTab || 'video' === activeTab || $('.videos.active').length || isStreetViewTour ) {
3274 $('#wpvr_item_tour_checklist__box').css('display', 'none');
3275 }else{
3276 $('#wpvr_item_tour_checklist__box').css('display', 'block');
3277 }
3278
3279 toggleSceneGallery(activeTab, panovideo);
3280 }
3281
3282 $(document).ready(function() {
3283 $(".rex-pano-tab-nav li").on( 'click', function() {
3284 var activeTab = jQuery(this).data('screen');
3285 if(handle_hotspot_tab(activeTab, false))
3286 return false;
3287 });
3288 });
3289
3290 function handle_hotspot_tab(activeTab, redirect) {
3291 let isReturn = false;
3292 if (activeTab && 'hotspot' === activeTab) {
3293 const activeScene = jQuery('.scene-nav li.active span').attr('data-index');
3294 const activeSceneId = $('#scene-' + activeScene).find(".form-group img").attr('src');
3295 let activeTabUrl = window?.wpvr_global_obj?.active_tab_url;
3296 if (!activeSceneId && redirect) {
3297 window.location.replace(activeTabUrl);
3298 isReturn = true;
3299 } else if(!activeSceneId && !redirect){
3300 alert(window?.wpvr_global_obj?.hotspot_warning_text);
3301 jQuery('.rex-pano-tab-nav li scene').addClass('active');
3302 isReturn = true;
3303 }
3304 }
3305 return isReturn;
3306 }
3307
3308
3309 function toggleSceneGallery(activeTab = null, panovideo = null) {
3310 activeTab = activeTab === null ? get_active_tab() : activeTab;
3311 panovideo = panovideo === null ? $("input[name='panovideo']:checked").val() : panovideo;
3312 if ((activeTab && ('video' === activeTab || 'streetview' === activeTab ) || ( panovideo === 'on' && ( 'floorPlan' === activeTab || 'backgroundTour' === activeTab || 'export' === activeTab)))) {
3313 jQuery('.scene-gallery').hide();
3314 } else {
3315 jQuery('.scene-gallery').show();
3316 }
3317 }
3318
3319 // Function to update the progress bar
3320 function updateProgress() {
3321 let totalItems = $('.wpvr-checklist-items').length; // Total number of checklist items
3322 let checkedItems = $('.wpvr-checklist-items:checked').length; // Number of checked items
3323
3324 // Calculate progress percentage
3325 let progress = Math.round((checkedItems / totalItems) * 100);
3326
3327 // Update progress bar
3328 $('#wpvr-progress-bar').css('width', progress + '%');
3329 $('#wpvr-progress-text').text(progress + '%');
3330
3331 // Change color of progress bar based on progress
3332 if (progress === 100) {
3333 $('#wpvr-progress-bar').css('background-color', 'green');
3334 $('#wpvr-progress-text').css('color', 'white');
3335 }else{
3336 $('#wpvr-progress-text').css('color', '#3F04FE');
3337 }
3338 }
3339
3340 updateProgress();
3341
3342 $(document).on("click", ".toppitch", function () {
3343 if (!$('#wpvr-check-hotspots').is(':checked')) {
3344 $('#wpvr-check-hotspots').prop('checked', true);
3345 $('#wpvr-check-hotspots').closest('.wpvr-checklist-item').css('color', '#0E003C');
3346 }
3347 updateProgress();
3348 });
3349
3350
3351 $(document).ready(function() {
3352 $(".rex-pano-tab .inner-nav-content .single-settings.has-children .vr-switcher-check").each(function() {
3353 if ($(this).is(':checked')) {
3354 $(this).parents('.single-settings').addClass('margin-bottom-remove');
3355 } else {
3356 $(this).parents('.single-settings').removeClass('margin-bottom-remove');
3357 }
3358 });
3359 });
3360
3361
3362
3363 $('.rex-pano-tab .inner-nav-content .single-settings.has-children .vr-switcher-check').on('change', function() {
3364 if ($(this).is(':checked')) {
3365 $(this).parents('.single-settings').addClass('margin-bottom-remove');
3366 } else {
3367 $(this).parents('.single-settings').removeClass('margin-bottom-remove');
3368 }
3369 });
3370
3371 // Function to handle visibility toggle based on checkbox state
3372 function toggleKeyboardZoom() {
3373 var isChecked = $("input[name='mouseZoom']").is(':checked');
3374 $('.mouse-zoom-control-settings-wrapper').toggle(isChecked);
3375 }
3376
3377 // Initial state setup on page load
3378 toggleKeyboardZoom();
3379
3380 // Event listener for checkbox changes using more specific selector
3381 $("input[name='mouseZoom']").on("change", toggleKeyboardZoom);
3382
3383
3384
3385
3386
3387 // Function to handle visibility toggle based on checkbox state
3388 function toggleKeyboardSettings() {
3389 var isChecked = $("input[name='draggable']").is(':checked');
3390 $('.mouse-dragable-control-settings-wrapper').toggle(isChecked);
3391 }
3392
3393 // Initial state setup on page load
3394 toggleKeyboardSettings();
3395
3396 // Event listener for checkbox changes using more specific selector
3397 $("input[name='draggable']").on("change", toggleKeyboardSettings);
3398
3399
3400
3401 // Function to handle visibility toggle based on checkbox state
3402 function toggleGallerySettings() {
3403 var isChecked = $("input[name='vrgallery']").is(':checked');
3404 $('.scene-gallery-settings-wrapper').toggle(isChecked);
3405 }
3406
3407 // Initial state setup on page load
3408 toggleGallerySettings();
3409
3410 // Event listener for checkbox changes using more specific selector
3411 $("input[name='vrgallery']").on("change", toggleGallerySettings);
3412
3413
3414
3415 // Function to handle visibility toggle based on checkbox state
3416 function toggleGyroSettings() {
3417 var isChecked = $("input[name='gyro']").is(':checked');
3418 $('.zyro-settings-wrapper').toggle(isChecked);
3419 }
3420
3421 // Initial state setup on page load
3422 toggleGyroSettings();
3423
3424 // Event listener for checkbox changes using more specific selector
3425 $("input[name='gyro']").on("change", toggleGyroSettings);
3426
3427
3428 // Function to handle visibility toggle based on checkbox state
3429 function toggleExplainerSwitch() {
3430 var isChecked = $("input[name='explainerSwitch']").is(':checked');
3431 $('.explainer-video-settings-wrapper').toggle(isChecked);
3432 }
3433
3434 // Initial state setup on page load
3435 toggleExplainerSwitch();
3436
3437 // Event listener for checkbox changes using more specific selector
3438 $("input[name='explainerSwitch']").on("change", toggleExplainerSwitch);
3439
3440
3441 // Function to handle visibility toggle based on checkbox state
3442 function toggleZoomSwitch() {
3443 var isChecked = $("input[name='globalzoom']").is(':checked');
3444 $('.set-zoom-perference-control-settings-wrapper').toggle(isChecked);
3445 }
3446
3447 // Initial state setup on page load
3448 toggleZoomSwitch();
3449
3450 // Event listener for checkbox changes using more specific selector
3451 $("input[name='globalzoom']").on("change", toggleZoomSwitch);
3452
3453
3454
3455
3456
3457 // Get initial checkbox value and convert to boolean
3458 var callToAction = $("input[name='calltoaction']").val();
3459 callToAction = callToAction == 'on' ? true : false;
3460
3461 // Show or hide the call-to-action section on page load
3462 if (callToAction) {
3463 $('.call-to-action').show();
3464 } else {
3465 $('.call-to-action').hide();
3466 }
3467
3468 // Toggle visibility of the call-to-action section on checkbox change
3469 $(document).on("change", "input[name='calltoaction']", function () {
3470 var calltoactionbutton = $(this).is(':checked') ? 'on' : 'off';
3471 if (calltoactionbutton == 'on') {
3472 $('.call-to-action').show();
3473 } else {
3474 $('.call-to-action').hide();
3475 }
3476 });
3477
3478
3479 // Toggle visibility of the ".custom-css-field" section based on the "customcss" checkbox state.
3480
3481 // 1. On page load:
3482 // - Get the current value of the "customcss" input.
3483 // - Convert 'on' to boolean true.
3484 // - Show or hide the ".custom-css-field" section accordingly.
3485
3486 var customCssEnable = $("input[name='customcss']").val();
3487 customCssEnable = customCssEnable == 'on' ? true : false;
3488
3489 if (customCssEnable) {
3490 $('.custom-css-field').show();
3491 } else {
3492 $('.custom-css-field').hide();
3493 }
3494
3495 // 2. On checkbox state change:
3496 // - Detect changes to the "customcss" checkbox.
3497 // - Use .is(':checked') to determine current state.
3498 // - Alert the value ('on' or 'off').
3499 // - Show or hide the ".custom-css-field" section accordingly.
3500
3501 $(document).on("change", "input[name='customcss']", function () {
3502 var custom_css_field = $(this).is(':checked') ? 'on' : 'off';
3503 alert(custom_css_field);
3504
3505 if (custom_css_field == 'on') {
3506 $('.custom-css-field').show();
3507 } else {
3508 $('.custom-css-field').hide();
3509 }
3510 });
3511
3512 // Run when the DOM is fully loaded
3513 $(document).ready(function() {
3514 // Only apply on admin panel
3515 if ($('body').hasClass('post-type-wpvr_item')) {
3516 // Apply fixes after preview is loaded
3517 $(document).on('click', '.panolenspreview', function() {
3518 setTimeout(fixFloorplanPointers, 2000);
3519 });
3520
3521 // Also apply when document is ready
3522 setTimeout(fixFloorplanPointers, 1000);
3523 }
3524 });
3525
3526 /**
3527 * Fix floorplan pointers to stay within image boundaries
3528 */
3529 function fixFloorplanPointers() {
3530 // Find all floorplan pointers in admin preview
3531 $('.wpvr-floor-map .floor-plan-pointer').each(function() {
3532 var $pointer = $(this);
3533 var $container = $pointer.closest('.wpvr-floor-map');
3534
3535 if ($container.length) {
3536 var containerWidth = $container.width();
3537 var containerHeight = $container.height();
3538 var pointerWidth = $pointer.outerWidth();
3539 var pointerHeight = $pointer.outerHeight();
3540
3541 // Get current position
3542 var currentLeft = parseInt($pointer.css('left'), 10);
3543 var currentTop = parseInt($pointer.css('top'), 10);
3544
3545 // Calculate safe boundaries
3546 var maxLeft = containerWidth - pointerWidth;
3547 var maxTop = containerHeight - pointerHeight;
3548
3549 // Store original position as custom properties for CSS clamp()
3550 $pointer.css('--x-pos', currentLeft + 'px');
3551 $pointer.css('--y-pos', currentTop + 'px');
3552
3553 // Ensure pointer stays within boundaries
3554 if (currentLeft < 0) {
3555 $pointer.css('left', '9px');
3556 } else if (currentLeft > maxLeft) {
3557 $pointer.css('left', (maxLeft - 9) + 'px');
3558 }
3559
3560 if (currentTop < 0) {
3561 $pointer.css('top', '9px');
3562 } else if (currentTop > maxTop) {
3563 $pointer.css('top', (maxTop - 9) + 'px');
3564 }
3565 }
3566 });
3567 }
3568
3569 // Check for floorplan pointers periodically in case they're added dynamically
3570 setInterval(fixFloorplanPointers, 3000);
3571
3572 $('.scene-setup').on('input', 'input[type="text"]', function () {
3573 // Escape < and > to prevent script execution when reading
3574 this.value = this.value.replace(/</g, "&lt;").replace(/>/g, "&gt;");
3575 });
3576
3577
3578 /**
3579 * WPVR Telemetry Tracking
3580 */
3581 $(document).ready(function() {
3582 // Global tracking helper
3583 window.wpvrTrackAdminEvent = function(eventName, properties = {}) {
3584 if (typeof wpvr_global_obj === 'undefined' || !wpvr_global_obj.ajaxurl) {
3585 return;
3586 }
3587
3588 $.ajax({
3589 url: wpvr_global_obj.ajaxurl,
3590 type: 'POST',
3591 data: {
3592 action: 'wpvr_track_telemetry_event',
3593 event_name: eventName,
3594 properties: properties,
3595 security: wpvr_global_obj.ajax_nonce
3596 }
3597 });
3598 };
3599
3600 // Track Upgrade Clicks
3601 $(document).on('click', 'a[href*="wpvr-pricing"], .go-pro-link, .wpvr-go-pro', function() {
3602 wpvrTrackAdminEvent('upgrade_clicked', { source: 'admin_link' });
3603 });
3604
3605 $(document).on('click', function(e) {
3606 var $target = $(e.target);
3607 var featureName = 'pro_feature';
3608 var isPaywall = false;
3609 var $context = null;
3610
3611 // Check 1: Wrapper with _is_pro class (e.g. wpvr_cardboard_disable_is_pro)
3612 var $proWrapper = $target.closest('[class*="_is_pro"]');
3613 if ($proWrapper.length > 0) {
3614 isPaywall = true;
3615 $context = $proWrapper;
3616 }
3617
3618 // Check 2: Standard Container with internal Pro badge (Nav menu, buttons, etc.)
3619 if (!isPaywall) {
3620 var $container = $target.closest('li, label, button, a, .wpvr-import-button');
3621 if ($container.length > 0) {
3622 var hasBadge = $container.find('.navigator-pro-tag, .pro-tag, .is-pro').length > 0 ||
3623 $container.hasClass('is-pro');
3624 if (hasBadge) {
3625 isPaywall = true;
3626 $context = $container;
3627 }
3628 }
3629 }
3630
3631 if (isPaywall && $context) {
3632 // 3. Extract Feature Name
3633 if ($context.attr('data-screen')) {
3634 featureName = $context.attr('data-screen');
3635 } else if ($context.find('input').length > 0) {
3636 featureName = $context.find('input').val();
3637 } else if ($context.hasClass('wpvr-import-button')) {
3638 featureName = 'import_tour';
3639 } else if ($context.attr('class') && $context.attr('class').match(/_is_pro/)) {
3640 // Try to find a label inside to get the feature name from 'for' attribute
3641 var $label = $context.find('label');
3642 if ($label.length > 0 && $label.attr('for')) {
3643 featureName = $label.attr('for');
3644 } else {
3645 // Fallback to class name minus _is_pro
3646 var match = $context.attr('class').match(/([a-zA-Z0-9_-]+)_is_pro/);
3647 if (match && match[1]) {
3648 featureName = match[1];
3649 }
3650 }
3651 }
3652
3653 // Normalize feature name
3654 featureName = featureName.replace(/-/g, '_').toLowerCase();
3655
3656 wpvrTrackAdminEvent('paywall_hit', { feature_name: featureName });
3657 }
3658 });
3659
3660 // Scene Pro Feature Image (Special Case)
3661 $(document).on('click', 'img[src*="scene-pro-feature.png"]', function() {
3662 wpvrTrackAdminEvent('paywall_hit', { feature_name: 'scene_pro_feature' });
3663 });
3664
3665 });
3666
3667 })(jQuery);
3668
3669
3670 // WPVR Hotspot Long-Press Mobile Support
3671 jQuery(document).ready(function($) {
3672 var isTouchDevice = ("ontouchstart" in window) || (navigator.maxTouchPoints > 0);
3673 var disOnHover = (typeof wpvr_obj !== 'undefined') ? wpvr_obj.dis_on_hover : undefined;
3674 var tipEnabled = (typeof wpvr_obj !== 'undefined') ? wpvr_obj.mobile_hotspot_tip : undefined;
3675 var shouldShowAlert = isTouchDevice && (disOnHover !== "1");
3676 if (shouldShowAlert) {
3677 setTimeout(function() {
3678 if (!$('.pnlm-container').length) {
3679 return;
3680 }
3681 $('.pnlm-hotspot-base, .pnlm-hotspot').each(function() {
3682 $(this).off('mouseenter mouseover mouseleave');
3683
3684 // Hide only the inner content <p>, not the hotspot pointer
3685 $(this).find('p').hide();
3686
3687 var longPressTimer;
3688 var isLongPress = false;
3689
3690 // Prevent click after long press
3691 $(this).off('click._wpvrHotspotFix').on('click._wpvrHotspotFix', function(e) {
3692 if ($(this).data('wpvr-longpress')) {
3693 e.preventDefault();
3694 e.stopImmediatePropagation();
3695 $(this).data('wpvr-longpress', false);
3696 return false;
3697 }
3698 });
3699
3700 $(this).on('touchstart', function(e) {
3701 isLongPress = false;
3702 var $hotspot = $(this);
3703
3704 // Hide inner content on touch start
3705 $hotspot.find('p').hide();
3706
3707 longPressTimer = setTimeout(function() {
3708 isLongPress = true;
3709 $hotspot.data('wpvr-longpress', true);
3710
3711 // Hide all other hotspot contents first
3712 $('.pnlm-hotspot-base p, .pnlm-hotspot p').hide();
3713
3714 // Show only this hotspot's content
3715 $hotspot.find('p').show();
3716 }, 600);
3717 });
3718
3719 $(this).on('touchend', function(e) {
3720 clearTimeout(longPressTimer);
3721 if (isLongPress) {
3722 e.preventDefault();
3723 e.stopPropagation();
3724 // Do NOT auto-hide after 2 seconds anymore
3725 // Content will stay open until user taps elsewhere
3726 } else {
3727 // Short tap: hide inner content, let click fire
3728 $(this).find('p').hide();
3729 }
3730 });
3731
3732 $(this).on('touchmove', function() {
3733 clearTimeout(longPressTimer);
3734 isLongPress = false;
3735 // Hide inner content if user starts panning
3736 $(this).find('p').hide();
3737 });
3738 });
3739
3740 // Hide hotspot content when tapping outside any hotspot
3741 $(document).on('touchstart.wpvrHotspotOutside', function(e) {
3742 // If the tap is not inside a hotspot or its content
3743 if (!$(e.target).closest('.pnlm-hotspot-base, .pnlm-hotspot').length) {
3744 $('.pnlm-hotspot-base p, .pnlm-hotspot p').hide();
3745 }
3746 });
3747
3748 // Hide other hotspot contents when another hotspot is long-pressed
3749 $('.pnlm-hotspot-base, .pnlm-hotspot').on('touchstart', function(e) {
3750 // Hide all other hotspot contents except the one being touched
3751 var $current = $(this);
3752 $('.pnlm-hotspot-base, .pnlm-hotspot').not($current).find('p').hide();
3753 });
3754
3755 if (tipEnabled == '1') {
3756 function showHotspotTip() {
3757 if (window.sessionStorage && sessionStorage.getItem('wpvrHotspotTipShown')) return;
3758 if (window.sessionStorage) {
3759 sessionStorage.setItem('wpvrHotspotTipShown', '1');
3760 }
3761 alert('Tip: On mobile devices, long-press a hotspot to show its hover content.');
3762 }
3763 $('.pnlm-container').on('touchstart.wpvrTip touchmove.wpvrTip', showHotspotTip);
3764 $('.pnlm-hotspot-base, .pnlm-hotspot').on('touchstart.wpvrTip', showHotspotTip);
3765 }
3766 }, 800);
3767 }
3768 });
3769