PageSourceSearch

https://www.mikerezinissan.com/app/themes/dv-framework/shortcodes/…/translation-switcher.js?ver=1.785.816

js mikerezinissan.com collected 2026-10-08 11:07:55 UTC 10,468 bytes, 238 lines download raw bytes

1(function($) {
2    // Cookie Helpers
3    function setCookie(name, value, days) {
4        let expires = "";
5        if (days) {
6            let date = new Date();
7            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
8            expires = "; expires=" + date.toUTCString();
9        }
10        document.cookie = name + "=" + (value || "") + expires + "; path=/";
11    }
12
13    function getCookie(name) {
14        let nameEQ = name + "=";
15        let ca = document.cookie.split(';');
16        for (let i = 0; i < ca.length; i++) {
17            let c = ca[i];
18            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
19            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
20        }
21        return null;
22    }
23
24    const debounce = window.DAPlacement ? window.DAPlacement.debounce : function(fn) { return fn; };
25
26    const decoder = $('<div/>');
27    function decodeEntities(html) {
28        return decoder.html(html).text();
29    }
30
31    $(document).ready(function() {
32        if (typeof daTranslationConfig === 'undefined' || !window.DAPlacement) return;
33
34        const container = $('#da-translation-switcher-container');
35        if (!container.length) return;
36
37        let lastDevice = null;
38        let isSuccessfullyMoved = false;
39
40        function moveSwitcher(force = false) {
41            const isMobile = window.DAPlacement.isMobile();
42            const currentDevice = window.DAPlacement.getDevice();
43
44            // Avoid redundant work if device hasn't changed and we're already in the DOM
45            if (!force && lastDevice === currentDevice && isSuccessfullyMoved && container.parent().length > 0) {
46                return true;
47            }
48
49            const position = isMobile ? daTranslationConfig.mobilePosition : daTranslationConfig.desktopPosition;
50            const selector = isMobile ? daTranslationConfig.mobileCustomSelector : daTranslationConfig.desktopCustomSelector;
51            const injType = isMobile ? daTranslationConfig.mobileInjectionType : daTranslationConfig.desktopInjectionType;
52
53            if (position === 'none') {
54                container.hide();
55                lastDevice = currentDevice;
56                isSuccessfullyMoved = true;
57                return true;
58            }
59
60            // Remove previous classes
61            container.removeClass('da-in-menu');
62
63            if (position === 'floater') {
64                const floaterConfig = (isMobile ? daTranslationConfig.mobileFloater : daTranslationConfig.desktopFloater) || {corner: 'br', offsetX: '20px', offsetY: '20px'};
65                window.DAPlacement.applyFloater(container, floaterConfig);
66            } else {
67                // Special handling for mobile menu to ensure it's inside the UL if possible
68                let injectSelector = selector;
69                let needsLiWrap = false;
70                if (position === 'menu' && selector) {
71                    const menuUl = $(selector).first().find('ul').first();
72                    if (menuUl.length) {
73                        injectSelector = null;
74                        needsLiWrap = true;
75                        switch (injType) {
76                            case 'before': container.insertBefore(menuUl); break;
77                            case 'prepend': container.prependTo(menuUl); break;
78                            case 'append': container.appendTo(menuUl); break;
79                            default: container.insertAfter(menuUl); break;
80                        }
81                    }
82                }
83
84                if (injectSelector !== null) {
85                    if (!window.DAPlacement.inject(container, injectSelector, injType)) {
86                        return false; // Target not found or no selector
87                    }
88                }
89
90                if (needsLiWrap && !container.parent().is('li')) {
91                    container.wrap('<li class="da-menu-switcher-wrapper" style="list-style:none;"></li>');
92                }
93
94                if (position === 'menu') {
95                    container.addClass('da-in-menu');
96                } else {
97                    // Reset fixed/absolute positioning if moved from floater
98                    window.DAPlacement.clearFloater(container);
99                }
100            }
101
102            // Update before/after markup based on device
103            const beforeMarkup = isMobile ? daTranslationConfig.mobileBefore : daTranslationConfig.desktopBefore;
104            const afterMarkup = isMobile ? daTranslationConfig.mobileAfter : daTranslationConfig.desktopAfter;
105            
106            container.find('.da-before-markup').html(beforeMarkup || '');
107            container.find('.da-after-markup').html(afterMarkup || '');
108
109            // Update appropriate style and labels based on device
110            const displayType = isMobile ? daTranslationConfig.mobileDisplayType : daTranslationConfig.desktopDisplayType;
111            
112            container.find('.lang-option, #languageDropdown option').each(function() {
113                const el = $(this);
114                const showFlag = displayType.indexOf('flag') !== -1;
115                const isCode = displayType.indexOf('code') !== -1;
116                const isPill = el.is('.lang-option');
117                
118                let text = isCode ? el.data('label-code') : el.data('label-name');
119                let label = text;
120
121                // Flags are always <img> tags; only pills render them inline.
122                // Dropdown options stay text-only — Select2's templates show
123                // the flag markup from data-label-flag instead.
124                if (showFlag && isPill) {
125                    const imgMatch = (el.data('label-flag') || '').match(/<img[^>]+>/);
126                    if (imgMatch) {
127                        label = imgMatch[0] + ' ' + text;
128                    }
129                }
130                
131                if (el.is('option')) {
132                    const decoded = decodeEntities(label);
133                    if (el.text() !== decoded) el.text(decoded);
134                } else {
135                    if (el.html() !== label) el.html(label);
136                }
137            });
138
139            // Decide style based on device and position
140            let style = (isMobile ? daTranslationConfig.mobileStyle : daTranslationConfig.desktopStyle) || 'pill';
141            
142            // Show appropriate style container
143            container.find('.da-switcher-style').hide();
144            container.find('.da-style-' + style).show();
145
146            // Initialize Select2 if dropdown style is used and Select2 is available
147            if (style === 'dropdown' && typeof $.fn.select2 !== 'undefined') {
148                const dropdown = container.find('#languageDropdown');
149                if (!dropdown.data('select2')) {
150                    dropdown.select2({
151                        minimumResultsForSearch: Infinity,
152                        templateResult: function(state) {
153                            if (!state.id) return state.text;
154                            const labelFlag = $(state.element).data('label-flag');
155                            if (labelFlag && labelFlag.indexOf('<img') !== -1) {
156                                return $('<span data-notranslate>' + labelFlag + '</span>');
157                            }
158                            return state.text;
159                        },
160                        templateSelection: function(state) {
161                            if (!state.id) return state.text;
162                            const labelFlag = $(state.element).data('label-flag');
163                            if (labelFlag && labelFlag.indexOf('<img') !== -1) {
164                                return $('<span data-notranslate>' + labelFlag + '</span>');
165                            }
166                            return state.text;
167                        },
168                        width: 'auto',
169                        dropdownAutoWidth: true,
170                        containerCssClass: 'da-select2-container',
171                        dropdownCssClass: 'da-select2-dropdown'
172                    });
173                }
174            }
175
176            container.show();
177            lastDevice = currentDevice;
178            isSuccessfullyMoved = true;
179            return true;
180        }
181
182        // Watcher for injection selector (tries every 100ms for up to 5s)
183        window.DAPlacement.watch(function() {
184            return moveSwitcher();
185        });
186
187        // Apply saved language on load
188        const savedLang = getCookie('da_lang');
189        if (savedLang) {
190            let attempts = 0;
191            const interval = setInterval(function() {
192                attempts++;
193                if (typeof lzSwitchLanguage === 'function') {
194                    lzSwitchLanguage(savedLang);
195                    
196                    // Sync UI (in case PHP was cached)
197                    container.find('.lang-option').removeClass('active');
198                    container.find('.lang-option[data-lang="' + s
198avedLang + '"]').addClass('active');
199                    container.find('#languageDropdown option').each(function() {
200                        if ($(this).data('lang-code') === savedLang) {
201                            $(this).prop('selected', true);
202                        }
203                    });
204
205                    clearInterval(interval);
206                }
207                if (attempts > 100) clearInterval(interval); // 10 seconds max
208            }, 100);
209        }
210
211        // Dropdown change handler
212        container.on('change', '#languageDropdown', function() {
213            const selectedLanguage = $(this).find('option:selected').data('lang-code');
214            setCookie('da_lang', selectedLanguage, 30);
215            if (typeof lzSwitchLanguage === 'function') {
216                lzSwitchLanguage(selectedLanguage);
217            }
218        });
219
220        // Pill Style change handler
221        container.on('click', '.lang-option', function(e) {
222            e.preventDefault();
223            const selectedLang = $(this).data('lang');
224            setCookie('da_lang', selectedLang, 30);
225            
226            container.find('.lang-option').removeClass('active');
227            $(this).addClass('active');
228
229            if (typeof lzSwitchLanguage === 'function') {
230                lzSwitchLanguage(selectedLang);
231            }
232        });
233
234        $(window).on('resize', debounce(function() {
235            moveSwitcher();
236        }, 150));
237    });
238})(jQuery);

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.