PageSourceSearch

https://pkmegapolis.ru/bitrix/js/bx365.captcha/observer.js?17875916524763

js pkmegapolis.ru collected 2026-10-02 19:27:24 UTC 4,763 bytes, 128 lines download raw bytes

1(function () {
2    var captchaPath = '/bitrix/tools/captcha.php';
3    var captchaSelector = 'img[src*="' + captchaPath + '"]';
4    var counter = 0;
5
6    function escapeHtml(value) {
7        return String(value).replace(/[&<>"']/g, function (symbol) {
8            return {
9                '&': '&amp;',
10                '<': '&lt;',
11                '>': '&gt;',
12                '"': '&quot;',
13                "'": '&#039;'
14            }[symbol];
15        });
16    }
17
18    function sidFromUrl(url) {
19        var match = String(url || '').match(/[?&]captcha_sid=([^&#]+)/);
20        return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : '';
21    }
22
23    function blockId(sid) {
24        counter += 1;
25        if (sid) {
26            return 'bx365-captcha-sid-' + sid.replace(/[^a-z0-9_-]/gi, '-') + '-' + counter;
27        }
28
29        return 'bx365-captcha-' + counter;
30    }
31
32    function ensureBlock(img, sid) {
33        var block = img.nextElementSibling;
34        if (block && block.classList && block.classList.contains('bx365-captcha')) {
35            if (sid) {
36                block.setAttribute('data-bx365-captcha-sid', sid);
37            }
38            return block;
39        }
40
41        var options = window.bx365CaptchaOptions || {};
42        var width = parseInt(options.canvasWidth, 10) || 180;
43        var height = parseInt(options.canvasHeight, 10) || 50;
44        var placeholder = options.placeholderText || '';
45        var refreshLabel = options.refreshLabel || placeholder;
46        var errorText = options.errorText || '';
47
48        block = document.createElement('div');
49        block.id = blockId(sid);
50        block.className = 'bx365-captcha';
51        if (sid) {
52            block.setAttribute('data-bx365-captcha-sid', sid);
53        }
54        block.innerHTML = '<canvas class="bx365-captcha__canvas" width="' + width + '" height="' + height + '"></canvas><span class="bx365-captcha__placeholder">' + escapeHtml(placeholder) + '</span><span class="bx365-captcha__error" role="alert">' + escapeHtml(errorText) + '</span><span class="bx365-captcha__overlay"><button class="bx365-captcha__refresh" type="button" aria-label="' + escapeHtml(refreshLabel) + '"><span class="bx365-captcha__refresh-icon" aria-hidden="true"></span></button></span><span class="bx365-captcha__progress-bar"></span>';
55        img.parentNode.insertBefore(block, img.nextSibling);
56
57        return block;
58    }
59
60    function processImage(img, refreshExisting) {
61        if (img.bx365CaptchaInternalUpdate) {
62            img.bx365CaptchaInternalUpdate = false;
63            return;
64        }
65
66        var sid = sidFromUrl(img.getAttribute('src'));
67        var block = img.nextElementSibling;
68        var hasBlock = block && block.classList && block.classList.contains('bx365-captcha');
69
70        img.setAttribute('bx365-captcha-source', img.getAttribute('bx365-captcha-source') || (hasBlock ? 'backend' : 'front'));
71        block = ensureBlock(img, sid);
72
73        if (refreshExisting && hasBlock && window.BX365Captcha && typeof window.BX365Captcha.load === 'function') {
74            window.BX365Captcha.load(block);
75        }
76    }
77
78    function scan(root) {
79        if (root.matches && root.matches(captchaSelector)) {
80            processImage(root, false);
81        }
82        if (root.querySelectorAll) {
83            Array.prototype.forEach.call(root.querySelectorAll(captchaSelector), function (img) {
84                processImage(img, false);
85            });
86        }
87    }
88
89    function preventCaptchaCopy(event) {
90        var target = event.target;
91        if (target && target.closest && target.closest('.bx365-captcha')) {
92            event.preventDefault();
93        }
94    }
95
96    var observer = new MutationObserver(function (mutations) {
97        mutations.forEach(function (mutation) {
98            if (mutation.type === 'attributes' && mutation.target.matches && mutation.target.matches(captchaSelector)) {
99                processImage(mutation.target, true);
100            }
101
102            Array.prototype.forEach.call(mutation.addedNodes || [], function (node) {
103                if (node.nodeType === 1) {
104                    scan(node);
105                }
106            });
107        });
108    });
109
110    if (document.readyState === 'loading') {
111        document.addEventListener('DOMContentLoaded', function () {
112            scan(document);
113        });
114    } else {
115        scan(document);
116    }
117
118    document.addEventListener('contextmenu', preventCaptchaCopy, true);
119    document.addEventListener('dragstart', preventCaptchaCopy, true);
120    document.addEventListener('selectstart', preventCaptchaCopy, true);
121
122    observer.observe(document.documentElement, {
123        childList: true,
124        subtree: true,
125        attributes: true,
126        attributeFilter: ['src']
127    });
128})();

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.