PageSourceSearch

https://3cenergy.org/wp-content/themes/ccce/js/iframe-translate.js?ver=1.0.2

js 3cenergy.org collected 2026-10-02 05:30:04 UTC 12,543 bytes, 330 lines download raw bytes

1/**
2 * Iframe Language Parameter Handler
3 * 
4 * This script detects when Google Translate changes the page language
5 * and appends the appropriate language query parameter to iframe URLs.
6 * 
7 * - Spanish (es): appends ?lang=es
8 * - Chinese Simplified (zh-CN): appends ?lang=zh-CN
9 */
10
11(function() {
12    'use strict';
13
14    /**
15     * Get current language from hostname, Google Translate cookie, or HTML lang attribute
16     * @returns {string|null} Language code or null if default language
17     */
18    function getCurrentLanguage() {
19        // Check hostname for subdomain-based translation (e.g., es.3cenergy.org)
20        var hostname = window.location.hostname.toLowerCase();
21        if (hostname.startsWith('es.')) {
22            return 'es';
23        }
24        if (hostname.startsWith('zh.') || hostname.startsWith('zh-cn.')) {
25            return 'zh-CN';
26        }
27
28        // Check Google Translate cookie
29        var cookieMatch = document.cookie.match(/(^|;) ?googtrans=([^;]*)(;|$)/);
30        if (cookieMatch && cookieMatch[2]) {
31            var langPair = cookieMatch[2].split('/');
32            if (langPair.length >= 3) {
33                return langPair[2]; // Returns language code like 'es' or 'zh-CN'
34            }
35        }
36
37        // Fallback to HTML lang attribute
38        var htmlLang = document.documentElement.getAttribute('lang');
39        if (htmlLang) {
40            return htmlLang.toLowerCase();
41        }
42
43        return null;
44    }
45
46    /**
47     * Get the language query parameter based on current language
48     * @param {string} lang - Language code
49     * @returns {string|null} Query parameter string or null
50     */
51    function getLangQueryParam(lang) {
52        if (!lang) {
53            return null;
54        }
55        
56        // Normalize language codes
57        lang = lang.toLowerCase();
58        
59        // Spanish
60        if (lang === 'es' || lang === 'es-es' || lang === 'es-mx' || lang.startsWith('es')) {
61            return '?lang=es';
62        }
63        
64        // Chinese Simplified
65        if (lang === 'zh-cn' || lang === 'zh' || lang.startsWith('zh-cn')) {
66            return '?lang=zh-CN';
67        }
68        
69        return null;
70    }
71
72    /**
73     * Check if Google Translate is currently actively translating (not just translated)
74     * This should only return true during the actual translation process
75     */
76    function isGoogleTranslateActive() {
77        // Only check for actual loading spinner, not other indicators
78        // The skiptranslate element can exist even when translation is done
79        var loadingIndicator = document.querySelector('.goog-te-spinner-pos');
80        if (loadingIndicator && loadingIndicator.offsetParent !== null) {
81            return true;
82        }
83        
84        return false;
85    }
86
87    /**
88     * Update iframe src URLs with language parameter
89     * @param {string} langParam - Language query parameter to append (null to remove)
90     */
91    function updateIframeUrls(langParam) {
92        // Extract lang value from langParam (e.g., "?lang=es" -> "es")
93        var langValue = langParam ? langParam.replace('?lang=', '') : null;
94
95        // Only update iframes that are not part of Google Translate's own elements
96        var iframes = document.querySelectorAll('iframe[src]');
97        
98        iframes.forEach(function(iframe) {
99            var currentSrc = iframe.getAttribute('src');
100            if (!currentSrc) {
101                return;
102            }
103
104            // Skip Google Translate's own iframes - be very thorough here
105            if (iframe.closest && (
106                iframe.closest('.goog-te-banner-frame') ||
107                iframe.closest('.goog-te-menu-frame') ||
108                iframe.closest('#google_translate_element') ||
109                iframe.closest('#google_translate_element2') ||
110                iframe.closest('.goog-te-banner') ||
111                iframe.closest('.skiptranslate')
112            )) {
113                return;
114            }
115
116            // Skip Google Tag Manager iframes (they shouldn't have lang params)
117            if (currentSrc.indexOf('googletagmanager.com') !== -1) {
118                return;
119            }
120
121            // Skip Google Translate iframes
122            if (currentSrc.indexOf('translate.google.com') !== -1) {
123                return;
124            }
125            
126            // Skip iframes that are inside Google Translate containers
127            var parent = iframe.parentElement;
128            while (parent && parent !== document.body) {
129                if (parent.classList && (
130                    parent.classList.contains('goog-te-banner-frame') ||
131                    parent.classList.contains('goog-te-menu-frame') ||
132                    parent.classList.contains('goog-te-banner') ||
133                    parent.id === 'google_translate_element' ||
134                    parent.id === 'google_translate_element2'
135                )) {
136                    return;
137                }
138                parent = parent.parentElement;
139            }
140
141            // Store original src if not already stored (before any modifications)
142            if (!iframe.hasAttribute('data-original-src')) {
143                // Use current src, but remove any existing lang param first
144                var cleanSrc = currentSrc.replace(/[?&]lang=[^&]*/, '');
145                iframe.setAttribute('data-original-src', cleanSrc);
146            }
147
148            // Get the original src (without lang param)
149            var originalSrc = iframe.getAttribute('data-original-src') || currentSrc.replace(/[?&]lang=[^&]*/, '');
150
151            // Parse URL to handle existing query strings
152            try {
153                var url = new URL(originalSrc, window.location.href);
154                
155                if (langValue) {
156                    // Set the lang parameter
157                    url.searchParams.set('lang', langValue);
158                } else {
159                    // Remove the lang parameter
160                    url.searchParams.delete('lang');
161                }
162                
163                var newSrc = url.toString();
164                
165                // Update immediately if the src changed
166                if (iframe.src !== newSrc) {
167                    iframe.src = newSrc;
168                }
169            } catch (e) {
170                // Fallback for browsers that don't support URL constructor
171                // or for relative URLs that can't be parsed
172                var cleanSrc = originalSrc.replace(/[?&]lang=[^&]*/, '');
173                var newSrc;
174                
175                if (langValue) {
176                    // Add lang parameter
177                    var separator = cleanSrc.indexOf('?') !== -1 ? '&' : '?';
178                    newSrc = cleanSrc + separator + 'lang=' + langValue;
179                } else {
180                    // Remove lang parameter (already removed in cleanSrc)
181                    newSrc = cleanSrc;
182                }
183                
184                if (iframe.src !== newSrc) {
185                    iframe.src = newSrc;
186                }
187            }
188        });
189    }
190
191    /**
192     * Main function to check and update iframe URLs
193     */
194    var lastProcessedLang = null;
195    var updateTimeout = null;
196    var isTranslating = false;
197    
198    function checkAndUpdateIframes() {
199        // Clear any pending updates
200        if (updateTimeout) {
201            clearTimeout(updateTimeout);
202        }
203        
204        var currentLang = getCurrentLanguage();
205        var langParam = getLangQueryParam(currentLang);
206        
207        // Very short delay to let Google Translate finish its work first
208        // Only delay if Google Translate is actively translating
209        var delay = isGoogleTranslateActive() ? 200 : 50;
210        
211        updateTimeout = setTimeout(function() {
212            // Update if language changed
213            if (langParam && currentLang !== lastProcessedLang) {
214                lastProcessedLang = currentLang;
215                updateIframeUrls(langParam);
216            } else if (!langParam && lastProcessedLang) {
217                // Language was reset to default (English), remove lang params
218                lastProcessedLang = null;
219                updateIframeUrls(null); // Pass null to remove lang params
220            } else if (langParam && currentLang === lastProcessedLang) {
221                // Language is the same but might need to update iframes that were added later
222                updateIframeUrls(langParam);
223            }
224        }, delay);
225    }
226
227    /**
228     * Monitor cookie changes (for Google Translate)
229     */
230    function monitorCookieChanges() {
231        var lastGoogtransCookie = null;
232        var cookieUpdateTimeout = null;
233        
234        // Get initial cookie value
235        var cookieMatch = document.cookie.match(/(^|;) ?googtrans=([^;]*)(;|$)/);
236        if (cookieMatch && cookieMatch[2]) {
237            lastGoogtransCookie = cookieMatch[2];
238        }
239        
240        setInterval(function() {
241            var cookieMatch = document.cookie.match(/(^|;) ?googtrans=([^;]*)(;|$)/);
242            var currentGoogtransCookie = cookieMatch && cookieMatch[2] ? cookieMatch[2] : null;
243            
244            // Only check if the googtrans cookie specifically changed
245            if (currentGoogtransCookie !== lastGoogtransCookie) {
246                lastGoogtransCookie = currentGoogtransCookie;
247                
248                // Clear any pending updates
249                if (cookieUpdateTimeout) {
250                    clearTimeout(cookieUpdateTimeout);
251                }
252                
253                // Update immediately when cookie changes
254                checkAndUpdateIframes();
255            }
256        }, 200); // Check every 200ms for faster response
257        
258        // Also periodically check for new iframes that might have been added
259        // This helps catch dynamically loaded iframes
260        setInterval(function() {
261            var currentLang = getCurrentLanguage();
262            var langParam = getLangQueryParam(currentLang);
263            if (langParam) {
264                // Check if there are iframes without lang param
265                var iframes = document.querySelectorAll('iframe[src]');
266                var needsUpdate = false;
267                for (var i = 0; i < iframes.length; i++) {
268                    var iframe = iframes[i];
269                    var src = iframe.getAttribute('src');
270                    if (src && 
271                        src.indexOf('googletagmanager.com') === -1 &&
272                        src.indexOf('translate.google.com') === -1 &&
273                        src.indexOf('lang=') === -1 &&
274                        !iframe.closest('.goog-te-banner-frame') &&
275                        !iframe.closest('.goog-te-menu-frame')) {
276                        needsUpdate = true;
277                        break;
278                    }
279                }
280                if (needsUpdate) {
281                    checkAndUpdateIframes();
282                }
283            }
284        }, 1000); // Check every second for new iframes
285    }
286
287    /**
288     * Monitor HTML lang attribute changes only (less intrusive)
289     * REMOVED: This was potentially interfering with Google Translate
290     * We'll rely on cookie monitoring instead which is more reliable
291     */
292    function monitorLangAttribute() {
293        // Disabled to avoid interference with Google Translate
294        // Cookie monitoring is sufficient and less intrusive
295    }
296
297    /**
298     * Initialize the script
299     */
300    function init() {
301        // Start immediately
302        if (document.readyState === 'loading') {
303            document.addEventListener('DOMContentLoaded', function() {
304                checkAndUpdateIframes();
305                // Start monitoring immediately
306                monitorCookieChanges();
307                monitorLangAttribute();
308            });
309        } else {
310            checkAndUpdateIframes();
311            // Start monitoring immediately
312            monitorCookieChanges();
313            monitorLangAttribute();
314        }
315
316        // Also check when Google Translate widget is interacted with
317        // Listen for clicks on language selector links (use bubble phase, not capture)
318        // REMOVED: This was potentially interfering with Google Translate
319        // We'll rely on cookie monitoring instead
320
321        // REMOVED: Direct monitoring of Google Translate select dropdown
322        // This was potentially interfering with Google Translate's functionality
323        // We'll rely on cookie monitoring instead which is less intrusive
324    }
325
326    // Start initialization
327    init();
328
329})();
330

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.