PageSourceSearch

https://maritime-executive.com/js/recaptcha-loader.js?v=v2025.10.21.115952

js maritime-executive.com collected 2026-10-01 06:30:01 UTC 3,924 bytes, 119 lines download raw bytes

1/**
2 * Conditional reCAPTCHA Loader
3 * Only loads reCAPTCHA when a form with g-recaptcha class is visible
4 */
5
6(function() {
7    'use strict';
8    
9    let recaptchaLoaded = false;
10    let recaptchaLoading = false;
11    
12    // Function to load reCAPTCHA script
13    function loadRecaptcha() {
14        if (recaptchaLoaded || recaptchaLoading) {
15            return;
16        }
17        
18        recaptchaLoading = true;
19        
20        const script = document.createElement('script');
21        script.src = 'https://www.google.com/recaptcha/api.js';
22        script.async = true;
23        script.defer = true;
24        
25        script.onload = function() {
26            recaptchaLoaded = true;
27            recaptchaLoading = false;
28            console.log('reCAPTCHA loaded successfully');
29            
30            // Re-initialize any existing reCAPTCHA elements
31            if (window.grecaptcha && window.grecaptcha.render) {
32                document.querySelectorAll('.g-recaptcha').forEach(function(element) {
33                    if (!element.hasAttribute('data-recaptcha-rendered')) {
34                        window.grecaptcha.render(element);
35                    }
36                });
37            }
38        };
39        
40        script.onerror = function() {
41            recaptchaLoading = false;
42            console.error('Failed to load reCAPTCHA');
43        };
44        
45        document.head.appendChild(script);
46    }
47    
48    // Function to check if reCAPTCHA is needed
49    function checkForRecaptcha() {
50        const recaptchaElements = document.querySelectorAll('.g-recaptcha');
51        
52        if (recaptchaElements.length > 0) {
53            // Check if any reCAPTCHA element is visible
54            const visibleElements = Array.from(recaptchaElements).filter(function(element) {
55                const rect = element.getBoundingClientRect();
56                return rect.width > 0 && rect.height > 0;
57            });
58            
59            if (visibleElements.length > 0 && !recaptchaLoaded && !recaptchaLoading) {
60                loadRecaptcha();
61            }
62        }
63    }
64    
65    // Use Intersection Observer to detect when reCAPTCHA elements come into view
66    if ('IntersectionObserver' in window) {
67        const observer = new IntersectionObserver(function(entries) {
68            entries.forEach(function(entry) {
69                if (entry.isIntersecting && entry.target.classList.contains('g-recaptcha')) {
70                    loadRecaptcha();
71                    observer.disconnect();
72                }
73            });
74        }, {
75            rootMargin: '50px' // Load when element is 50px away from viewport
76        });
77        
78        // Observe all reCAPTCHA elements
79        document.querySelectorAll('.g-recaptcha').forEach(function(element) {
80            observer.observe(element);
81        });
82    } else {
83        // Fallback for older browsers
84        let checkInterval;
85        
86        function startChecking() {
87            checkInterval = setInterval(function() {
88                checkForRecaptcha();
89                if (recaptchaLoaded) {
90                    clearInterval(checkInterval);
91                }
92            }, 500);
93        }
94        
95        // Start checking after DOM is ready
96        if (document.readyState === 'loading') {
97            document.addEventListener('DOMContentLoaded', startChecking);
98        } else {
99            startChecking();
100        }
101    }
102    
103    // Also check when forms are focused (user might be about to submit)
104    document.addEventListener('focusin', function(event) {
105        if (event.target.closest('.g-recaptcha')) {
106            loadRecaptcha();
107        }
108    });
109    
110    // Check when user scrolls near forms
111    let scrollTimeout;
112    window.addEventListener('scroll', function() {
113        clearTimeout(scrollTimeout);
114        scrollTimeout = setTimeout(function() {
115            checkForRecaptcha();
116        }, 100);
117    });
118    
119})();

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.