PageSourceSearch

https://radio-online.ru/templates/Radio/js/feature-loader.js?v=3.2.8

js radio-online.ru collected 2026-10-01 14:35:04 UTC 5,745 bytes, 158 lines download raw bytes

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.