PageSourceSearch

https://altvpn.world/js/select-changer.js?0.0.291

js altvpn.world collected 2026-10-10 00:10:55 UTC 3,401 bytes, 82 lines download raw bytes

1function selectChanger() {
2    function initSelectChanger() {
3        const userAgent = new MobileDetect(window.navigator.userAgent);
4        const isMobile = userAgent.mobile() || userAgent.phone() || userAgent.tablet();
5        const nodesToReplace = document.querySelectorAll('.custom-select');
6        if (isMobile) {
7            replaceCustomWithNative(userAgent, nodesToReplace);
8        }
9    }
10
11    initSelectChanger();
12
13    function replaceCustomWithNative(userAgent, nodesToReplace) {
14        [].forEach.call(nodesToReplace, (node) => {
15            const selectItems = node.querySelector('.select-items');
16            if (!selectItems) {
17                return;
18            }
19            const optionsNodes = node.querySelector('.select-items').children;
20            const parsedOptionsValues = parseOptions(optionsNodes);
21            const isCities = parsedOptionsValues[0].classList.contains('cities');
22            const customSelectInputNode = node.querySelector('input');
23            const inputAttributeValues = parseInputAttributesValue(customSelectInputNode);
24            node = removeChildren(node);
25            node.classList.add('native-select-wrapper');
26            node.classList.remove('custom-select');
27            const selectNode = createSelectNode(inputAttributeValues, parsedOptionsValues, isCities);
28            node.appendChild(selectNode);
29        });
30    }
31
32    function parseOptions(optionNodes) {
33        const selectOptions = [];
34        [].forEach.call(optionNodes, (optionNode) => {
35            const optionDataObject = Object.create(null);
36            optionDataObject['value'] = optionNode.getAttribute('data-value');
37            optionDataObject['cost'] = optionNode.getAttribute('data-cost');
38            optionDataObject['classList'] = optionNode.classList;
39            optionDataObject['label'] = optionNode.textContent;
40            selectOptions.push(optionDataObject);
41        });
42        return selectOptions;
43    }
44
45    function parseInputAttributesValue(inputNode) {
46        const name = inputNode.getAttribute('name');
47        const value = inputNode.getAttribute('value');
48        const cost = inputNode.getAttribute('cost');
49        return {
50            name,
51            value
52        };
53    }
54
55    function removeChildren(node) {
56        node.querySelectorAll('*').forEach(n => n.remove());
57        return node;
58    }
59
60   function createSelectNode(inputAttributeValues, parsedOptionsValues, isCities) {
61       const nativeSelect = document.createElement('select');
62       nativeSelect.setAttribute('name', inputAttributeValues['name']);
63       nativeSelect.setAttribute('value', inputAttributeValues['value']);
64       nativeSelect.classList.add('native-select');
65       if (isCities) {
66           nativeSelect.setAttribute('cost', inputAttributeValues['cost']);
67       }
68       parsedOptionsValues.forEach((attributeObject) => {
69           const option = document.createElement('option');
70           option.textContent = attributeObject['label'];
71           option.setAttribute('value', attributeObject['value']);
72           if (isCities) {
73               option.setAttribute('cost', attributeObject['cost']);
74               option.classList.add('cities');
75               option.classList.add(attributeObject['classList'][1]);
76           }
77           nativeSelect.appendChild(option);
78       });
79       return nativeSelect;
80   }
81}
82selectChanger();

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.