PageSourceSearch

https://www.newsukraine.com.ua/wp-content/plugins/Duallang-main/assets/js/duallang-frontend.js?ver=1.3.25

js newsukraine.com.ua collected 2026-09-24 22:48:58 UTC 4,484 bytes, 97 lines download raw bytes

1/**
2 * DualLang WP — фронтовий скрипт.
3 *
4 * 1) Мова для AJAX/REST. На сторінці додаткової мови кожен запит теми до
5 *    admin-ajax.php чи /wp-json/ того ж сайту отримує заголовок X-DualLang-Lang.
6 *    Без нього «Завантажити ще», фільтри, живий пошук віддавали б контент
7 *    основною мовою й посилання без /xx/. Патчимо XMLHttpRequest (його
8 *    використовує jQuery.ajax) і fetch — цього достатньо для будь-якої теми.
9 *
10 * 2) Випадний перемикач (віджет/шорткод): відкриття кліком/дотиком/клавіатурою,
11 *    закриття кліком поза межами або Escape. Пункти в меню теми обробляє сама
12 *    тема — їх цей код не чіпає.
13 */
14(function () {
15    'use strict';
16
17    var cfg = window.DualLangWP || {};
18    var lang = cfg.lang || '';
19    var primary = cfg.primary || '';
20    var header = cfg.header || 'X-DualLang-Lang';
21
22    function sameOrigin(url) {
23        if (!url) { return false; }
24        try {
25            var u = new URL(String(url), window.location.href);
26            return u.origin === window.location.origin;
27        } catch (e) {
28            return false;
29        }
30    }
31
32    if (lang && lang !== primary) {
33        // XMLHttpRequest
34        if (window.XMLHttpRequest && XMLHttpRequest.prototype) {
35            var origOpen = XMLHttpRequest.prototype.open;
36            var origSend = XMLHttpRequest.prototype.send;
37            XMLHttpRequest.prototype.open = function (method, url) {
38                this.__duallangSame = sameOrigin(url);
39                return origOpen.apply(this, arguments);
40            };
41            XMLHttpRequest.prototype.send = function () {
42                if (this.__duallangSame) {
43                    try { this.setRequestHeader(header, lang); } catch (e) { /* заголовок уже виставлено або запит не відкрито */ }
44                }
45                return origSend.apply(this, arguments);
46            };
47        }
48        // fetch
49        if (window.fetch) {
50            var origFetch = window.fetch;
51            window.fetch = function (input, init) {
52                try {
53                    var url = (typeof input === 'string') ? input : (input && input.url);
54                    if (sameOrigin(url)) {
55                        init = init || {};
56                        var h = new Headers(init.headers || (typeof input !== 'string' && input && input.headers) || undefined);
57                        if (!h.has(header)) { h.set(header, lang); }
58                        init.headers = h;
59                    }
60                } catch (e) { /* не наш запит — віддаємо як є */ }
61                return origFetch.call(this, input, init);
62            };
63        }
64    }
65
66    // ── Випадний перемикач ─────────────────────────────────────────────────
67    function closeAll(except) {
68        var open = document.querySelectorAll('.duallang-language-switcher .duallang-menu-dropdown.active');
69        for (var i = 0; i < open.length; i++) {
70            if (open[i] !== except) {
71                open[i].classList.remove('active');
72                var t = open[i].querySelector('.duallang-dropdown-toggle');
73                if (t) { t.setAttribute('aria-expanded', 'false'); }
74            }
75        }
76    }
77
78    document.addEventListener('click', function (e) {
79        var toggle = e.target.closest ? e.target.closest('.duallang-language-switcher .duallang-dropdown-toggle') : null;
80        if (toggle) {
81            e.preventDefault();
82            var li = toggle.parentNode;
83            var willOpen = !li.classList.contains('active');
84            closeAll(li);
85            li.classList.toggle('active', willOpen);
86            toggle.setAttribute('aria-expanded', willOpen ? 'true' : 'false');
87            return;
88        }
89        if (!(e.target.closest && e.target.closest('.duallang-language-switcher'))) {
90            closeAll(null);
91        }
92    });
93
94    document.addEventListener('keydown', function (e) {
95        if (e.key === 'Escape' || e.key === 'Esc') { closeAll(null); }
96    });
97})();

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.