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

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

265 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function($) {
2 'use strict';
3
4 /**
5 * All of the code for your public-facing JavaScript source
6 * should reside in this file.
7 *
8 * Note: It has been assumed you will write jQuery code here, so the
9 * $ function reference has been prepared for usage within the scope
10 * of this function.
11 *
12 * This enables you to define handlers, for when the DOM is ready:
13 *
14 * $(function() {
15 *
16 * });
17 *
18 * When the window is loaded:
19 *
20 * $( window ).load(function() {
21 *
22 * });
23 *
24 * ...and/or other possibilities.
25 *
26 * Ideally, it is not considered best practise to attach more than a
27 * single DOM-ready or window-load handler for a particular page.
28 * Although scripts in the WordPress core, Plugins and Themes may be
29 * practising this, we should strive to set a better example in our own work.
30 */
31
32 })(jQuery);
33
34 function wpvrSanitizeHtml(rawHtml) {
35 if (!rawHtml || typeof rawHtml !== 'string') return '';
36 var clean = rawHtml.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
37 try {
38 var parser = new DOMParser();
39 var doc = parser.parseFromString(clean, 'text/html');
40 var elements = doc.body.querySelectorAll('*');
41 for (var i = 0; i < elements.length; i++) {
42 var el = elements[i];
43 var tag = el.tagName.toLowerCase();
44 if (['script', 'object', 'embed', 'applet', 'link', 'meta', 'base'].indexOf(tag) !== -1) {
45 el.parentNode && el.parentNode.removeChild(el);
46 continue;
47 }
48 var attrs = el.attributes;
49 for (var a = attrs.length - 1; a >= 0; a--) {
50 var attrName = attrs[a].name.toLowerCase();
51 var attrVal = attrs[a].value;
52 if (attrName.indexOf('on') === 0) {
53 el.removeAttribute(attrs[a].name);
54 } else if (['href', 'src', 'action', 'formaction', 'xlink:href'].indexOf(attrName) !== -1) {
55 if (/^\s*(javascript|vbscript|data:text\/html):/i.test(attrVal)) {
56 el.removeAttribute(attrs[a].name);
57 }
58 }
59 }
60 }
61 return doc.body.innerHTML;
62 } catch (e) {
63 return clean.replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, '').replace(/\s*on\w+\s*=\s*[^\s>]+/gi, '');
64 }
65 }
66 window.wpvrSanitizeHtml = wpvrSanitizeHtml;
67
68 function wpvrhotspot(hotSpotDiv, hotspotData) {
69 const args = hotspotData && hotspotData.on_click_content ? hotspotData.on_click_content : '';
70
71 if (args) {
72 const hasTextContent = args.replace(/<[^>]*>/g, '').trim() !== '';
73 const hasMediaContent = /<(img|video|audio|iframe|embed|object)\b[^>]*>/i.test(args);
74 const hasOtherContent = args.replace(/<(p|br|div|span)\b[^>]*\/?>/gi, '').trim() !== '';
75
76 if (hasTextContent || hasMediaContent || hasOtherContent) {
77 const cleanArgs = wpvrSanitizeHtml(args.replace(/\\/g, ''));
78
79 const $wrapper = jQuery(hotSpotDiv.target).parent().siblings(".custom-ifram-wrapper");
80 $wrapper.find('.custom-ifram').html(cleanArgs);
81 $wrapper.fadeIn();
82 jQuery(hotSpotDiv.target).closest(".pano-wrap").addClass("show-modal");
83 }
84 }
85 }
86 window.wpvrhotspot = wpvrhotspot;
87
88 function wpvrtooltip(hotSpotDiv, args) {
89 if (args) {
90 const hasTextContent = args.replace(/<[^>]*>/g, '').trim() !== '';
91 const hasMediaContent = /<(img|video|audio|iframe|embed|object)\b[^>]*>/i.test(args);
92 const hasOtherContent = args.replace(/<(p|br|div|span)\b[^>]*\/?>/gi, '').trim() !== '';
93
94 if (hasTextContent || hasMediaContent || hasOtherContent) {
95 const cleanArgs = wpvrSanitizeHtml(args.replace(/\\/g, ''));
96
97 hotSpotDiv.classList.add('custom-tooltip');
98 const p = document.createElement('p');
99 const content = document.createElement('div');
100 content.className = 'wpvr-tooltip-content';
101 content.innerHTML = cleanArgs;
102 p.appendChild(content);
103 hotSpotDiv.appendChild(p);
104
105 p.style.marginLeft = -(p.scrollWidth - hotSpotDiv.offsetWidth) / 2 + 'px';
106 p.style.marginTop = -p.scrollHeight - 12 + 'px';
107
108 // Optional: inject style once
109 if (!document.getElementById('wpvr-tooltip-style')) {
110 const style = document.createElement('style');
111 style.id = 'wpvr-tooltip-style';
112 style.textContent = `
113 .table, .table td, .table th {
114 border: 1px solid #dee2e6;
115 border-collapse: collapse;
116 padding: 8px;
117 }
118 `;
119 document.head.appendChild(style);
120 }
121 }
122 }
123 }
124 window.wpvrtooltip = wpvrtooltip;
125
126 jQuery(document).ready(function($) {
127
128 $(".cross").on("click", function(e) {
129 e.preventDefault();
130 $(this).parent(".custom-ifram-wrapper").fadeOut();
131 $(this).parents(".pano-wrap").removeClass("show-modal");
132
133 $('.vr-iframe').attr('src', '');
134 // $('iframe').attr('src', $('iframe').attr('src'));
135 if ($('#wpvr-video').length != 0) {
136 $('#wpvr-video').get(0).pause();
137 }
138
139 $(this).parent(".custom-ifram-wrapper").find('.custom-ifram').empty();
140
141 });
142
143 });
144
145 jQuery(document).ready(function($) {
146
147 var notice_active = (typeof wpvr_public !== 'undefined') ? wpvr_public.notice_active : '';
148 var notice = (typeof wpvr_public !== 'undefined') ? wpvr_public.notice : '';
149 if (notice_active == "true") {
150 if (!$.cookie("wpvr_mobile_notice")) {
151 if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
152 if ($(".pano-wrap")[0]) {
153 $('body').append("<div class='wpvr-mobile-notice'><p>" + notice + "</p> <span class='notice-close'><i class='fa fa-times'></i></span></div>");
154 }
155 }
156 }
157 }
158
159 $('.wpvr-mobile-notice .notice-close').on('click', function() {
160 $('.wpvr-mobile-notice').fadeOut();
161 $.cookie('wpvr_mobile_notice', 'true');
162 });
163 });
164
165 // WPVR Hotspot Long-Press Mobile Support
166 jQuery(document).ready(function($) {
167 var isTouchDevice = ("ontouchstart" in window) || (navigator.maxTouchPoints > 0);
168 var disOnHover = (typeof wpvr_public !== 'undefined') ? wpvr_public.dis_on_hover : undefined;
169 var tipEnabled = (typeof wpvr_public !== 'undefined') ? wpvr_public.mobile_hotspot_tip : undefined;
170 var shouldShowAlert = isTouchDevice && (disOnHover !== "1");
171 if (shouldShowAlert) {
172 setTimeout(function() {
173 if (!$('.pnlm-container').length) {
174 return;
175 }
176 $('.pnlm-hotspot-base, .pnlm-hotspot').each(function() {
177 $(this).off('mouseenter mouseover mouseleave');
178
179 // Hide only the inner content <p>, not the hotspot pointer
180 $(this).find('p').hide();
181
182 var longPressTimer;
183 var isLongPress = false;
184
185 // Prevent click after long press
186 $(this).off('click._wpvrHotspotFix').on('click._wpvrHotspotFix', function(e) {
187 if ($(this).data('wpvr-longpress')) {
188 e.preventDefault();
189 e.stopImmediatePropagation();
190 $(this).data('wpvr-longpress', false);
191 return false;
192 }
193 });
194
195 $(this).on('touchstart', function(e) {
196 isLongPress = false;
197 var $hotspot = $(this);
198
199 // Hide inner content on touch start
200 $hotspot.find('p').hide();
201
202 longPressTimer = setTimeout(function() {
203 isLongPress = true;
204 $hotspot.data('wpvr-longpress', true);
205
206 // Hide all other hotspot contents first
207 $('.pnlm-hotspot-base p, .pnlm-hotspot p').hide();
208
209 // Show only this hotspot's content
210 $hotspot.find('p').show();
211 }, 600);
212 });
213
214 $(this).on('touchend', function(e) {
215 clearTimeout(longPressTimer);
216 if (isLongPress) {
217 e.preventDefault();
218 e.stopPropagation();
219 // Do NOT auto-hide after 2 seconds anymore
220 // Content will stay open until user taps elsewhere
221 } else {
222 // Short tap: hide inner content, let click fire
223 $(this).find('p').hide();
224 }
225 });
226
227 $(this).on('touchmove', function() {
228 clearTimeout(longPressTimer);
229 isLongPress = false;
230 // Hide inner content if user starts panning
231 $(this).find('p').hide();
232 });
233 });
234
235 // Hide hotspot content when tapping outside any hotspot
236 $(document).on('touchstart.wpvrHotspotOutside', function(e) {
237 // If the tap is not inside a hotspot or its content
238 if (!$(e.target).closest('.pnlm-hotspot-base, .pnlm-hotspot').length) {
239 $('.pnlm-hotspot-base p, .pnlm-hotspot p').hide();
240 }
241 });
242
243 // Hide other hotspot contents when another hotspot is long-pressed
244 $('.pnlm-hotspot-base, .pnlm-hotspot').on('touchstart', function(e) {
245 // Hide all other hotspot contents except the one being touched
246 var $current = $(this);
247 $('.pnlm-hotspot-base, .pnlm-hotspot').not($current).find('p').hide();
248 });
249
250 if (tipEnabled == '1') {
251 function showHotspotTip() {
252 if (window.sessionStorage && sessionStorage.getItem('wpvrHotspotTipShown')) return;
253 if (window.sessionStorage) {
254 sessionStorage.setItem('wpvrHotspotTipShown', '1');
255 }
256 alert('Tip: On mobile devices, long-press a hotspot to show its hover content.');
257 }
258 $('.pnlm-container').on('touchstart.wpvrTip touchmove.wpvrTip', showHotspotTip);
259 $('.pnlm-hotspot-base, .pnlm-hotspot').on('touchstart.wpvrTip', showHotspotTip);
260 }
261 }, 800);
262 }
263 });
264
265