1(function (window, document) { 2 'use strict'; 3 4 var current = document.currentScript; 5 var base = current && current.src ? current.src.replace(/[^/?#]+(?:[?#].*)?$/, '') : '/templates/Radio/js/'; 6 var loaded = Object.create(null); 7 var scanning = false; 8 var scanTimer = 0; 9 10 var features = [ 11 { 12 key: 'static-pages', 13 selector: '[data-static-page]', 14 files: ['static-pages.js?v=1.8'] 15 }, 16 { 17 key: 'home-player', 18 selector: '[data-home-radio-player]', 19 files: ['home-radio-player.js?v=2.5.24'] 20 }, 21 { 22 key: 'favorites-sort', 23 selector: '[data-favorites-sort-button], .js-fav-sort-btn, [data-news-id][draggable="true"]', 24 test: function () { 25 return /(?:^|\/)favorites(?:\/|$)/i.test(String(window.location.pathname || '')) || 26 !!document.querySelector('[data-favorites-sort-button], .js-fav-sort-btn'); 27 }, 28 files: ['favorites-sort-div.js?v=2.7'] 29 }, 30 { 31 key: 'playlists-menu', 32 selector: '.side-playlists', 33 files: ['playlists-menu.js?v=2.2.47'] 34 }, 35 { 36 key: 'programme', 37 test: function () { 38 var roots = document.querySelectorAll('[data-radio-programme-managed], [data-radio-programme], [data-radio-program], [data-programme], [data-radio-schedule], .radio-programme, .radio-program, .radio-schedule, .programme-schedule, .program-schedule'); 39 if (!roots.length) return false; 40 var configured = window.RadioRelayConfig && Array.isArray(window.RadioRelayConfig.programmeStationIds) 41 ? window.RadioRelayConfig.programmeStationIds.map(Number) 42 : [16, 70, 74, 108, 2270, 2545, 2557, 14757]; 43 for (var i = 0; i < roots.length; i++) { 44 var id = Number(roots[i].getAttribute && roots[i].getAttribute('data-radio-id') || 0); 45 if (id && configured.indexOf(id) !== -1) return true; 46 if (!id && !roots[i].hasAttribute('data-radio-programme-managed')) return true; 47 } 48 return false; 49 }, 50 files: ['programme-loader.js?v=3.2.4', 'programme-tabs.js?v=2.2.45'] 51 } 52 ]; 53 54 function absoluteUrl(file) { 55 try { return new URL(file, base).href; } 56 catch (error) { return base + file; } 57 } 58 59 function alreadyPresent(url) { 60 var scripts = document.scripts || []; 61 for (var i = 0; i < scripts.length; i++) { 62 if (scripts[i].src === url) return true; 63 } 64 return false; 65 } 66 67 function loadFile(file) { 68 var url = absoluteUrl(file); 69 if (loaded[url]) return loaded[url]; 70 if (alreadyPresent(url)) { 71 loaded[url] = Promise.resolve(url); 72 return loaded[url]; 73 } 74 75 loaded[url] = new Promise(function (resolve, reject) { 76 var script = document.createElement('script'); 77 script.src = url; 78 script.async = false; 79 script.setAttribute('data-radio-feature-script', '1'); 80 script.onload = function () { resolve(url); }; 81 script.onerror = function () { 82 if (script.parentNode) script.parentNode.removeChild(script); 83 delete loaded[url]; 84 reject(new Error('Ðе ÑдалоÑÑ Ð·Ð°Ð³ÑÑзиÑÑ ' + url)); 85 }; 86 (document.head || document.documentElement).appendChild(script); 87 }); 88 return loaded[url]; 89 } 90 91 function featureNeeded(feature) { 92 if (window.RadioLowBandwidth && window.RadioLowBandwidth.isEnabled && window.RadioLowBandwidth.isEnabled() && (feature.key === 'programme' || feature.key === 'playlists-menu')) return false; 93 if (typeof feature.test === 'function' && feature.test()) return true; 94 return !!(feature.selector && document.querySelector(feature.selector)); 95 } 96 97 function loadFeature(feature) { 98 if (feature.loading || feature.ready || !featureNeeded(feature)) return; 99 feature.loading = true; 100 var chain = Promise.resolve(); 101 feature.files.forEach(function (file) { 102 chain = chain.then(function () { return loadFile(file); }); 103 }); 104 chain.then(function () { 105 feature.ready = true; 106 feature.loading = false; 107 try { 108 document.dispatchEvent(new CustomEvent('radio:feature-loaded', {detail: {key: feature.key}})); 109 } catch (error) {} 110 }).catch(function () { 111 feature.loading = false;
112 }); 113 } 114 115 function scan() { 116 scanTimer = 0; 117 if (scanning) return; 118 scanning = true; 119 try { 120 for (var i = 0; i < features.length; i++) loadFeature(features[i]); 121 } finally { 122 scanning = false; 123 } 124 } 125 126 function scheduleScan(delay) { 127 window.clearTimeout(scanTimer); 128 scanTimer = window.setTimeout(scan, Number(delay || 0)); 129 } 130 131 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', scan, {once: true}); 132 else scan(); 133 134 document.addEventListener('radio:content-updated', function () { scheduleScan(0); }, false); 135 document.addEventListener('radio:low-bandwidth-change', function () { scheduleScan(0); }, false); 136 document.addEventListener('wajax:success', function () { scheduleScan(0); }, false); 137 document.addEventListener('wajax:complete', function () { scheduleScan(20); }, false); 138 if (window.jQuery) { 139 try { window.jQuery(document).on('pjax:success pjax:end pjax:complete', function () { scheduleScan(0); }); } 140 catch (error) {} 141 } 142 143 if ('MutationObserver' in window) { 144 var target = document.getElementById('wajax') || document.body; 145 if (target) { 146 new MutationObserver(function (mutations) { 147 for (var i = 0; i < mutations.length; i++) { 148 if (mutations[i].addedNodes && mutations[i].addedNodes.length) { 149 scheduleScan(30); 150 return; 151 } 152 } 153 }).observe(target, {childList: true, subtree: true}); 154 } 155 } 156 157 window.RadioFeatureLoader = {scan: scan, loadFile: loadFile}; 158})(window, document);
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.