PageSourceSearch

https://cavetown.nl/wp-content/themes/flatsome-child-2024/js/main.js?ver=1791447036

js cavetown.nl collected 2026-10-08 08:20:50 UTC 14,663 bytes, 431 lines download raw bytes

1document.addEventListener('DOMContentLoaded', function() { 
2
3    let pulser = document.querySelector('.pdp__pulse')
4    let pulserText = document.querySelector('.pdp__pulse__text')
5
6    const useRandomForTesting = false;
7
8    if (document.querySelector('.stock.in-stock')) {
9        const stockElement = document.querySelector('.stock.in-stock');
10
11        pulser.style.display = "flex";
12        pulser.style.color = "#008000";
13        pulser.classList.add('has-stock')
14
15        if (stockElement.textContent.includes("Op voorraad")) {
16            pulserText.textContent = 'Beperkte voorraad';
17        } else {
18            pulserText.textContent = stockElement.textContent;
19        }
20
21    } else {
22        const pdpTimeElement = document.querySelector('.pdp__time');
23
24        if (pdpTimeElement) {
25            const pdpTimeText = pdpTimeElement.textContent.trim();
26            
27            if (pdpTimeText.includes('werkdagen')) {
28
29                const messagesOrange = ctMessagesOrange;
30                const messagesGreen = ctMessagesGreen;
31                
32                const allMessages = [...messagesOrange, ...messagesGreen];
33                const orangeCount = messagesOrange.length;
34                
35                let messageIndex;
36                
37                if (useRandomForTesting) {
38                    messageIndex = Math.floor(Math.random() * allMessages.length);
39                } else {
40                    const productId = window.item?.product_id ? parseInt(window.item.product_id) : 0;
41
42                    const now = new Date();
43                    const dayOfYear = Math.floor((now - new Date(now.getFullYear(), 0, 0)) / 86400000);
44                    const baseSeed = now.getFullYear() + dayOfYear;
45            
46                    // Combine base seed with product ID
47                    const productSeed = baseSeed + productId;
48                    
49                    messageIndex = productSeed % allMessages.length;  
50                }
51
52                const message = allMessages[messageIndex];
53                
54                const color = messageIndex < orangeCount ? "#008000" : "#008000";
55
56                pulser.style.display = "flex";
57                pulser.style.color = color;
58                pulserText.textContent = message;
59            }
60        }
61    }
62});
63
64
65let swiperContainers = [...document.querySelectorAll('.swiper-container')]
66
67
68if (swiperContainers.length > 0) {
69    swiperContainers.forEach(container => {
70        let parent = container.closest(".js-swiper-container-parent")
71        let next = parent.querySelector('.swiper-next')
72        let prev = parent.querySelector('.swiper-prev')
73    
74        const swiper = new Swiper(container, {
75            // Optional parameters
76            slidesPerView: 'auto', 
77        
78            // Navigation arrows
79            navigation: {
80                nextEl: next,
81                prevEl: prev,
82            }, 
83    
84            spaceBetween: 20,
85        });
86    })
87}
88
89
90const tooltips = document.querySelectorAll('.js-hotspot');
91
92if (tooltips.length > 0) {
93    tooltips.forEach((tooltip) => {
94        tooltip.addEventListener('click', (event) => {
95            if (!tooltip.closest('.ct-hotspot').classList.contains('active')) {
96                tooltips.forEach((t) => t.closest('.ct-hotspot').classList.remove('active'));
97                tooltip.closest('.ct-hotspot').classList.add('active'); 
98
99                adjustTooltipPosition(tooltip.closest('.ct-hotspot').querySelector('.ct-hotspot-tile'))
100            } else {
101                tooltips.forEach((t) => t.closest('.ct-hotspot').classList.remove('active')); 
102            } 
103
104        });
105    });
106
107    // Add click event listener to the window to remove 'active' class
108    window.addEventListener('click', (e) => { 
109        const hotspotElement = e.target.closest('.ct-hotspot');
110        
111        if (hotspotElement) {
112            if (hotspotElement.classList.contains('ct-hotspot')) {
113                return false
114            }
115        } else {
116            tooltips.forEach((t) => t.closest('.ct-hotspot').classList.remove('active')); 
117        }
118    });
119}
120
121function adjustTooltipPosition(tooltip) { 
122    const tooltipRect = tooltip.getBoundingClientRect();
123    const windowWidth = window.innerWidth;
124    const windowHeight = window.innerHeight;
125    
126    // Check and adjust the position if the tooltip is going outside the right boundary
127    if (tooltipRect.right > windowWidth) {
128        console.log('1')
129        tooltip.style.transform = 'translate(-90%,0)';
130
131        // tooltip.style.left = `${windowWidth - tooltipRect.width}px`;
132    }
133
134    // Check and adjust the position if the tooltip is going outside the bottom boundary
135    if (tooltipRect.bottom > windowHeight) {
136        console.log('2')
137
138        // tooltip.style.top = `${windowHeight - tooltipRect.height}px`;
139    }
140
141    // Check and adjust the position if the tooltip is going outside the left boundary
142    if (tooltipRect.left < 0) {
143        console.log('3')
144
145        tooltip.style.transform = 'translate(-15%,0)';
146    }
147
148    // Check and adjust the position if the tooltip is going outside the top boundary
149    if (tooltipRect.top < 0) {
150        console.log('4')
151        // tooltip.style.top = '0px';
152    }
153}
154
155
156
157document.addEventListener('DOMContentLoaded', function() { 
158    const quicklinksParents = document.querySelectorAll('.product-quicklinks')
159
160    quicklinksParents.forEach(quickLinksParent => {
161        const quickLinks = quickLinksParent.querySelectorAll('.quicklink-btn') 
162        quickLinks.forEach(quicklink => {
163            quicklink.addEventListener('click', function(e) {
164                // console.log(quicklink.dataset.target)
165                // console.log(document.querySelector(`[data-section="${quicklink.dataset.target}"]`))
166                
167                e.preventDefault();
168                const targetSections = document.querySelectorAll(`[data-section="${quicklink.dataset.target}"]`); 
169                scrollToSection(targetSections);
170            })
171        }) 
172    })
173
174    function scrollToSection(targetSections) {
175        if (targetSections) {
176            const headerOffset = 125; // Adjust this value based on your fixed header height
177            var elementPosition
178            if (window.innerWidth <= 849) {
179                const hasJsPDPClass = Array.from(targetSections).some(section => section.classList.contains('js-pdp-section'));
180
181                if (hasJsPDPClass) {
182                    elementPosition = targetSections[0].getBoundingClientRect().top;
183
184                } else {
185
186                    elementPosition = targetSections[1].getBoundingClientRect().top;
187                }
188
189            } else {
190                elementPosition = targetSections[0].getBoundingClientRect().top;
191
192            }
193            const offsetPosition = elementPosition + window.pageYOffset - headerOffset;
194 
195
196            window.scrollTo({
197                top: offsetPosition,
198                behavior: 'smooth'
199            });
200        }
201    }
202
203
204
205
206
207    const readmores = document.querySelectorAll('.js-text-read-more')
208
209    if (readmores) {
210        readmores.forEach(readmore => {
211            const btn = readmore.querySelector('.js-text-read-more-btn')  
212    
213            btn.addEventListener('click', function(e) {
214                e.preventDefault()
215                readmore.classList.add('is-open')
216            })
217        })
218    
219        var toggleButton = document.getElementById('toggle-attributes');
220        var hiddenAttributes = document.querySelectorAll('.hidden-attribute');
221    
222        if (toggleButton) {
223            toggleButton.addEventListener('click', function() {
224                // Check if attributes are currently hidden
225                var isHidden = hiddenAttributes[0].style.display === 'none' || hiddenAttributes[0].style.display === '';
226    
227                hiddenAttributes.forEach(function(attribute) {
228                    if (isHidden) {
229                        attribute.style.display = 'table-row'; // Show hidden attributes
230                        toggleButton.textContent = 'Toon minder specificaties'; // Update button text
231                        toggleButton.classList.add('active')
232                    } else {
233                        attribute.style.display = 'none'; // Hide the attributes
234                        toggleButton.textContent = 'Toon meer specificaties'; // Reset button text
235                        toggleButton.classList.remove('active')
236                    }
237                });
238            });
239    
240            // Ensure attributes are hidden on page load
241            hiddenAttributes.forEach(function(attribute) {
242                attribute.style.display = 'none';
243            });
244        }
245    }
246});
247
248const ctGoogleMapsConfig = {
249    apiKey: 'AIzaSyAoQGtUwcur1anZNTzZA6gxXXiKYiRBSos',
250    lat: 52.0154703,
251    lng: 5.1039262,
252    zoom: 12,
253    markerIcon: '/wp-content/uploads/2026/04/marker.png',
254    mapStyle: [
255        {
256            "featureType": "all",
257            "elementType": "labels.text",
258            "stylers": [
259                {
260                    "color": "#878787"
261                }
262            ]
263        },
264        {
265            "featureType": "all",
266            "elementType": "labels.text.stroke",
267            "stylers": [
268                {
269                    "visibility": "off"
270                }
271            ]
272        },
273        {
274            "featureType": "landscape",
275            "elementType": "all",
276            "stylers": [
277                {
278                    "color": "#f9f5ed"
279                }
280            ]
281        },
282        {
283            "featureType": "road.highway",
284            "elementType": "all",
285            "stylers": [
286                {
287                    "color": "#f5f5f5"
288                }
289            ]
290        },
291        {
292            "featureType": "road.highway",
293            "elementType": "geometry.stroke",
294            "stylers": [
295                {
296                    "color": "#c9c9c9"
297                }
298            ]
299        },
300        {
301            "featureType": "water",
302            "elementType": "all",
303            "stylers": [
304                {
305                    "color": "#aee0f4"
306                }
307            ]
308        }
309    ]
310};
311
312function initCtGoogleMap() {
313    const mapEl = document.getElementById('ct-google-map');
314    if (!mapEl) return;
315
316    const position = { lat: ctGoogleMapsConfig.lat, lng: ctGoogleMapsConfig.lng };
317
318    const map = new google.maps.Map(mapEl, {
319        center: position,
320        zoom: ctGoogleMapsConfig.zoom,
321        styles: ctGoogleMapsConfig.mapStyle,
322        fullscreenControl: false,
323        streetViewControl: false,
324        zoomControl: false,
325        rotateControl: false,
326        scaleControl: false,
327        cameraControl: false,
328        keyboardShortcuts: false,
329        disableDefaultUI: true
330    });
331
332    const markerOptions = { position: position, map: map };
333    if (ctGoogleMapsConfig.markerIcon) {
334        markerOptions.icon = {
335            url: ctGoogleMapsConfig.markerIcon,
336            scaledSize: new google.maps.Size(64, 64)
337        };
338    }
339
340    const marker = new google.maps.Marker(markerOptions);
341
342    marker.addListener('click', function() {
343        const url = 'https://www.google.com/maps/dir/?api=1&destination=' +
344            ctGoogleMapsConfig.lat + ',' + ctGoogleMapsConfig.lng;
345        window.open(url, '_blank');
346    });
347}
348
349window.initCtGoogleMap = initCtGoogleMap;
350
351document.addEventListener('DOMContentLoaded', function() {
352    if (!document.getElementById('ct-google-map')) return;
353
354    const script = document.createElement('script');
355    script.src = 'https://maps.googleapis.com/maps/api/js?key=' + ctGoogleMapsConfig.apiKey + '&callback=initCtGoogleMap';
356    script.async = true;
357    script.defer = true;
358    document.head.appendChild(script);
359});
360
361document.addEventListener('DOMContentLoaded', function() {
362    const container = document.querySelector('.product-short-description');
363    if (!container) return;
364
365    const maxChars = 140; // change this to whatever you want
366    const fullHtml  = container.innerHTML.trim();
367    const fullText  = container.textContent.trim();
368
369    // Nothing to do if it's already short
370    if (fullText.length <= maxChars) return;
371
372    const previewText = fullText.slice(0, maxChars);
373
374    // Store original content in data attributes
375    container.dataset.fullHtml    = fullHtml;
376    container.dataset.previewText = previewText;
377    container.dataset.expanded    = 'false';
378
379    function renderPreview() {
380        container.innerHTML =
381            '<span class=\"short-description-preview\">' +
382                container.dataset.previewText +
383                '&hellip;' +
384            '</span> ' +
385            '<button type=\"button\" class=\"short-description-toggle ct-button--outline fw-700\"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path stroke="#1D1D1B" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.333" d="M14.665 4.668 8 11.335 1.332 4.668"/></svg>Toon meer</button>';
386    }
387
388    function renderFull() {
389        container.innerHTML =
390            container.dataset.fullHtml +
391            '<button type=\"button\" class=\"short-description-toggle short-description-toggle--less ct-button--outline fw-700\"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path stroke="#1D1D1B" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.333" d="m1.333 11.334 6.666-6.667 6.667 6.667"/></svg>Toon minder</button>';
392    }
393
394    function renderFullNoButton() {
395        container.innerHTML = container.dataset.fullHtml;
396    }
397
398    function applyState() {
399        if (window.innerWidth < 850) {
400            if (container.dataset.expanded === 'true') {
401                renderFull();
402            } else {
403                renderPreview();
404            }
405        } else {
406            renderFullNoButton();
407        }
408    }
409
410    let wasNarrow = window.innerWidth < 850;
411    applyState();
412
413    // Toggle on click (event delegation – survives innerHTML changes)
414    container.addEventListener('click', function(event) {
415        const toggle = event.target.closest('.short-description-toggle');
416        if (!toggle) return;
417
418        const expanded = container.dataset.expanded === 'true';
419        container.dataset.expanded = expanded ? 'false' : 'true';
420        applyState();
421    });
422
423    // Re-render only when the viewport crosses the 850px boundary
424    window.addEventListener('resize', function() {
425        const isNarrow = window.innerWidth < 850;
426        if (isNarrow === wasNarrow) return;
427        wasNarrow = isNarrow;
428        applyState();
429    });
430
431});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.