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

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

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