PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 8.5.69
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v8.5.69
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 8.5.4 All 221 releases
wpvr / admin / js / wpvr-admin.js

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

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