Versions 4pda

Вывод версий приложений в Избранном 4pda, показ обновленных приложений

  1. // ==UserScript==
  2. // @name Versions 4pda
  3. // @namespace http://4pda.to/forum/index.php
  4. // @version 1.6.2
  5. // @description:ru Вывод версий приложений в Избранном 4pda, показ обновленных приложений
  6. // @author Azat-777 (Ник на 4pda: Azat-777, mail: aflitonovazat@gmail.com)
  7. // @icon http://s.4pda.to/kkRM7z1nbI3gbG5E7r0a561qtdKnE2GlKhz1ipnv.png
  8. // @match http*://4pda.to/forum/index.php?act=fav*
  9. // @match http*://4pda.to/forum/index.php?showtopic=*
  10. // @grant GM_xmlhttpRequest
  11. // @license MIT
  12. // @history:ru когда-то давно: первый релиз
  13. // @history:ru 26.07.2017: допиливание мелочей
  14. // @history:ru 31.07.2017: расширение функционала скрипта: подробная информация о каждом пользователе в топиках
  15. // @history:ru 04.08.2017: добавлено мигание 'NEW' (скрыто)
  16. // @history:ru 02.01.2018: небольшие правки кода
  17. // @history:ru 10.05.2018: изменение списка обновленных приложений
  18. // @history:ru 11.05.2018: мелкие правки и исправления
  19. // @history:ru 20.05.2018: добавлено удаление пробелов в начале и конце названий версий, чтобы из-за пробелов версия не определялась как новая
  20. // @history:ru 16.08.2018: теперь обновления не исчезают с обновлением страницы, для ручного скрытия обновлений добавлена кнопка
  21. // @history:ru 17.08.2018: правка вчерашних ошибок, добавление мелочей (title и переход к последнему непрочитанному сообщению в теме
  22. // @history:ru обновленного приложения); реализация скрытия обновлений по одному: убрад мигание NEW для обновлений, т.к. уже неактуально
  23. // @history:ru 20.08.2018: починен показ кнопки скрытия отдельного обновления; в консоли выводится объем загруженого XHR-запросами траффика
  24. // @history:ru 06.05.2019: кроме слова 'версия' другой текст, если он был, не удалялся, поправлено
  25. // @history:ru 01.06.2019: слово 'версия' не заменялось на 'v.', если после него не было пробела. Недоработка в регулярках. Поправлено
  26. // @history:ru 02.06.2019: добавлена функция отключения проверки обновлений для выбранных приложений (могут быть ошибки)
  27. // @history:ru 14.02.2020: исправлена ошибка, при которой выводился текст на месте версии
  28. // @history:ru 05.07.2022: исправлена ошибка в коде, из-за которой таблица с обновленными версиями приложений появлялась снова после скрытия
  29. // @history:ru 09.06.2023: мелкие и незначительные правки для обеспечения полной работоспособности скрипта, наверное...
  30. // @history:ru 25.05.2025: в таблицу обновлений (в том числе и в таблицу ЧС) добавлен столбец с датами последнего обновления приложения/игры;
  31. // @history:ru убрал в таблице для версий приставку 'v.' за ненадобностью
  32. // @history:ru ВНИМАНИЕ: некоторые приложения, относящие к VPN, не будут подгружаться в таблицу обновлений и показывать версии,
  33. // @history:ru т.к. могут быть проблемы с доступом к этим темам без включенного VPN
  34. // @description Вывод версий приложений в Избранном 4pda, показ обновленных приложений
  35. // ==/UserScript==
  36.  
  37. (function() {
  38. 'use strict';
  39. //============================================================
  40. // получение ссылки текущей страницы
  41. var URL = window.document.URL;
  42. //log(URL);
  43. //============================================================
  44. // удаляем рекламу и центрируем логотип 4pda
  45. var tbody = document.getElementsByTagName('tbody')[0],
  46. td = tbody.getElementsByTagName('td');
  47. td[1].remove();
  48. td[0].align = 'center';
  49. //============================================================
  50. var favURL = '4pda.to/forum/index.php?act=fav', i,
  51. head = document.getElementsByTagName('head')[0];
  52. //var topicURL = 'http://4pda.to/forum/index.php?showtopic=';
  53.  
  54. // спойлер с объявлениями всегда скрыт
  55. if(document.querySelector('#gc_1, #go_1')) {
  56. document.querySelector('#go_1').style.display = 'none';
  57. document.querySelector('#gc_1').style.display = 'none';
  58. }
  59. var l = 0, // счетчик
  60. totalKB = 0,
  61. totalMB = 0;
  62.  
  63. function log(text) {
  64. return console.log(text);
  65. }
  66.  
  67. // Избранное
  68. if (~URL.indexOf(favURL))
  69. {
  70. //localStorage
  71. //localStorage.clear();
  72. //============================================================
  73. // модифицирование встроенной функции модерации тем в своем избранном
  74. var savedIDs,
  75. form = document.querySelector('#fav-sel-form'),
  76. select = form.querySelector('select'),
  77. option = document.createElement('option'),
  78. values = '';
  79. option.value = 'not_show_updates';
  80. option.innerHTML = 'Не уведомлять об обновлениях (mod)';
  81. select.insertBefore(option, select.firstChild);
  82.  
  83. // сохранение IDов выбранных тем в localStorage
  84. option.onclick = function() {
  85. checkSavedIDs();
  86. if(savedIDs == '-1') {
  87. values = form.querySelector('input').value;
  88. } else {
  89. values = savedIDs + ',' + form.querySelector('input').value;
  90. }
  91. values = values.split(',');
  92. values = unique(values);
  93. localStorage.setItem('savedIDs', values);
  94. checkBan();
  95. }
  96.  
  97. // удаление из массива одинаковых IDов
  98. function unique(arr) {
  99. var obj = {};
  100. for (var i = 0; i < arr.length; i++) {
  101. var str = arr[i];
  102. obj[str] = true; // запомнить строку в виде свойства объекта
  103. }
  104. return Object.keys(obj); // или собрать ключи перебором для IE8-
  105. }
  106.  
  107. checkSavedIDs();
  108. function checkSavedIDs() {
  109. if(localStorage.getItem('savedIDs') === null) {
  110. localStorage.setItem('savedIDs', '-1');
  111. }
  112. savedIDs = localStorage.getItem('savedIDs');
  113. savedIDs = savedIDs.split(',');
  114. }
  115.  
  116. // добавление в строке названий приложений их версий
  117. var ver;
  118. // находим таблицу
  119. var tbl = document.getElementsByClassName('ipbtable')[0];
  120. var tbody2 = tbl.getElementsByTagName('tbody')[0];
  121. var _tr = tbody2.getElementsByTagName('tr');
  122. // запихиваем в tr нужные нам строки таблицы
  123. var tr = [], id;
  124. for(i=0; i<_tr.length; i++)
  125. {
  126. if (_tr[i].hasAttribute('data-item-fid')) { // отсортировываем из таблицы только темы
  127. tr.push(_tr[i]); // запихиваем в массив tr
  128. }
  129. }
  130. var trLength = tr.length
  131. var name = []; // названия тем
  132. for (i=0; i<trLength; i++)
  133. {
  134. var tmp = tr[i].getElementsByTagName('td')[1].getElementsByTagName('span')[0].getElementsByTagName('a')[0];
  135. id = tr[i].getAttribute('data-item-fid');
  136. getVersion(tmp.getAttribute('href'), i, id);
  137. //getVersion(tmp.href, i);
  138. name.push(tmp);
  139. }
  140. //=====================================================
  141. // добавление счетчика с количеством новых версий приложений
  142. var count = 0;
  143. var main_tbl = document.createElement('table');
  144. main_tbl.id = 'main_tbl';
  145. main_tbl.innerHTML = `<tbody><tr><td id="one" style="vertical-align: top;"></td> <td id="two" style="vertical-align: top;"></td></tr></tbody>`;
  146.  
  147. var _span = document.createElement('span');
  148. _span.style.color = 'black';
  149. var _span2 = document.createElement('span');
  150. _span2.style.color = 'black';
  151. var navstrip = document.getElementById('navstrip');
  152. //=====================================================
  153. var app_name,
  154. saveToHideName = [],
  155. saveToHideVer = [];
  156. /*_new = ' <mytag class="new" style="color: red"><b>NEW</b></mytag>',*/
  157.  
  158. function getVersion(link, i, id)
  159. {
  160. var XHR = ("onload" in new XMLHttpRequest()) ? XMLHttpRequest : XDomainRequest;
  161. var xhr = new XHR();
  162. xhr.open('GET', link, true);
  163. xhr.send();
  164. xhr.onload = function()
  165. {
  166. if(this.readyState === 4)
  167. {
  168. if (this.status === 200)
  169. {
  170. var response = xhr.responseText;
  171. var parser = new DOMParser();
  172. var doc = parser.parseFromString(response, 'text/html');
  173. var tbl = doc.getElementsByClassName('ipbtable');
  174. for (var j=0; j<tbl.length; j++)
  175. {
  176. if (tbl[j].hasAttribute('data-post'))
  177. {
  178. var tbody = tbl[j].getElementsByTagName('tbody')[0],
  179. tr2 = tbody.getElementsByTagName('tr')[1],
  180. td = tr2.getElementsByTagName('td')[1],
  181. div = td.getElementsByClassName('postcolor')[0],
  182. span = div.getElementsByTagName('span'),
  183. date_i = div.getElementsByTagName('i')[0],
  184. date = date_i.getElementsByTagName('b')[0].innerHTML;
  185. //console.log(date.innerHTML);
  186. for (var k=0; k<span.length; k++)
  187. {
  188. // версии приложений
  189. if (span[k].getAttribute('style') == 'font-size:12pt;line-height:100%')
  190. {
  191. if (~span[k].innerHTML.toLowerCase().indexOf('верси'))
  192. {
  193. // замена
  194. var replace_ver = span[k].innerHTML,
  195. alt_ver, t;
  196. // если тема не была открыта
  197. if (~name[i].innerHTML.indexOf('<strong>'))
  198. {
  199. replace_ver = replace_ver.toLowerCase().replace(/[А-Яа-я\s]*верси[ия]:[\s]*/, 'v.').replace(/<[\/]*b[r]*>/g, '').trim();
  200. if(~replace_ver.indexOf('v.')) {
  201. alt_ver = replace_ver;
  202. } else {
  203. alt_ver = '---';
  204. }
  205. var alt_name;
  206. alt_name = name[i].innerHTML.replace(/<[\/]*strong>/g, '');
  207. // если приложение в списке игнорируемых, т.е. не проходит проверку на обновления
  208. t = true;
  209. for(var l=0; l<savedIDs.length; l++) {
  210. if(id == savedIDs[l]) {
  211. t = false;
  212. getBannedApps(alt_name, alt_ver, id, date);
  213. //continue;
  214. }
  215. }
  216. // если приложение не в игноре + сравнение версий: текущей полученной и сохраненной в локальном хранилище
  217. if (t && alt_ver.localeCompare(localStorage.getItem(alt_name)) !== 0) {
  218. showNotif(alt_name, alt_ver, date);
  219. //console.log(name[i].innerHTML, alt_ver);
  220. }
  221. }
  222. // если тема была открыта и просмотрена
  223. else
  224. {
  225. replace_ver = replace_ver.toLowerCase().replace(/<b>[А-Яа-я\s]*верси[ия]:[\s]*/, 'v.').replace(/<[\/]*b>/g, '').trim();
  226. if(~replace_ver.indexOf('v.')) {
  227. alt_ver = replace_ver;
  228. } else {
  229. alt_ver = '---';
  230. }
  231. // если приложение в списке игнорируемых, т.е. не проходит проверку на обновления
  232. t = true;
  233. for(l=0; l<savedIDs.length; l++) {
  234. if(id == savedIDs[l]) {
  235. t = false;
  236. getBannedApps(name[i].innerHTML, alt_ver, id, date);
  237. //continue;
  238. }
  239. }
  240. // если приложение не в игноре + сравнение версий: текущей полученной и сохраненной в локальном хранилище
  241. if (t && alt_ver.localeCompare(localStorage.getItem(name[i].innerHTML)) !== 0 ) {
  242. showNotif(name[i].innerHTML, alt_ver, date);
  243. }
  244. }
  245. // вывод обновленных приложений вверху
  246. function showNotif(alt_name, alt_ver, date) {
  247. hideBtn.style.display = 'inline'; // показываем скрытую кнопку, если есть обновления
  248. //replace_ver += _new; // прибавляем тэг 'NEW' для новой версии
  249. count++;
  250. var goto = '<a href="'+link+'&amp;view=getnewpost"><img src="//4pda.to/s/PXtiWhZDsz1g8WshSfmv6ItmpiBfFE4lDMF4ZupTkMv.gif" alt=">N" title="Перейти к первому непрочитанному" border="0"></a> '
  251. app_name = goto + '<a href="'+link+'" title="Перейти к первому сообщению">'+alt_name + '</a>';
  252. saveToHideName.push(alt_name);
  253. saveToHideVer.push(alt_ver);
  254. showUpdates(app_name, alt_ver, date);
  255. }
  256. // если replace_ver содержит готовый шаблон "v.xxx", добавляем его к названию приложения
  257. if(~replace_ver.indexOf('v.')) {
  258. replace_ver = '<font color="#8A2BE2"> ' + replace_ver + '</font>'; // добавление цвета для наглядности
  259. name[i].innerHTML += replace_ver;
  260. }
  261. }
  262. break;
  263. }
  264. }
  265. break;
  266. }
  267. }
  268. }
  269. }
  270. };
  271. xhr.onerror = function() {
  272. log('onerror');
  273. alert('Ошибка');
  274. };
  275. xhr.onloadend = function(event) {
  276. //log('onloadend');
  277. totalKB += (event.loaded/1024); // подсчет загруженного траффика
  278. totalMB += (event.loaded/1024/1024);
  279. if(++l === trLength) {
  280. addEvent(); // вешаем обработчик событий строки (появление/скрытие кноки "Скрыть")
  281. hideApp(); // скрытие строки с обновленным приложением
  282. console.log('Скачано XHR-запросами:', totalKB.toFixed(2), 'КБ |', totalMB.toFixed(2), 'МБ'); // вывод объема скачанного
  283. }
  284. };
  285. xhr.onprogress = function(event) {
  286. //log('onprogress');
  287. };
  288. }
  289. // переопределяем стиль для кнопок
  290. var btnStyle = document.createElement('style');
  291. btnStyle.type = 'text/css';
  292. var _s = `
  293. .myBtn {
  294. display: inline-block;
  295. font-family: arial,sans-serif;
  296. font-size: 10px;
  297. font-weight: bold;
  298. color: rgb(68,68,68);
  299. text-decoration: none;
  300. user-select: none;
  301. padding: .1em 1.2em;
  302. outline: none;
  303. border: 1px solid rgba(0,0,0,.1);
  304. border-radius: 2px;
  305. background: rgb(245,245,245) linear-gradient(#f4f4f4, #f1f1f1);
  306. transition: all .218s ease 0s;
  307. }
  308. .myBtn:hover {
  309. color: rgb(24,24,24);
  310. border: 1px solid rgb(198,198,198);
  311. background: #f7f7f7 linear-gradient(#f7f7f7, #f1f1f1);
  312. box-shadow: 0 1px 2px rgba(0,0,0,.1);
  313. }
  314. .myBtn:active {
  315. color: rgb(51,51,51);
  316. border: 1px solid rgb(204,204,204);
  317. background: rgb(238,238,238) linear-gradient(rgb(238,238,238), rgb(224,224,224));
  318. box-shadow: 0 1px 2px rgba(0,0,0,.1) inset;
  319. }`;
  320. var _st = document.createTextNode(_s);
  321. btnStyle.appendChild(_st);
  322. head.appendChild(btnStyle);
  323.  
  324. //navstrip.appendChild(_span);
  325. navstrip.appendChild(main_tbl);
  326. var one = document.querySelector('#main_tbl #one'),
  327. two = document.querySelector('#main_tbl #two');
  328. one.appendChild(_span);
  329. two.appendChild(_span2);
  330.  
  331. _span.innerHTML = 'Обновлений: <font id="_cnt" color="red">' + count + '</font> <input id="hideBtn" class="myBtn" type="button" value="Скрыть обновления" style="display: none;" /> <br/>' +
  332. `<table class="_tbl" style="border-collapse: collapse; border: 0px">
  333. <thead> <tr> <th class="brown-right-line">#</th> <th class="brown-right-line">Название</th> <th class="brown-right-line">Версия</th> <th title="Дата последнего обновления" class="date">Дата обновления</th> </tr> </thead>
  334. <tbody> </tbody>
  335. </table>`;
  336. var _tbl = document.querySelector('._tbl'),
  337. _tbody = _tbl.querySelector('tbody'),
  338. _cnt = document.querySelector('#_cnt'),
  339. n = 0;
  340. _tbl.style.display = 'none';
  341.  
  342. var tblStyle = document.createElement('style');
  343. tblStyle.type = 'text/css';
  344. var s = `
  345. ._tbl th {
  346. color: brown; background-color: white; text-align: center; padding: 2px; letter-spacing: 0px;
  347. }
  348. ._tbl td {
  349. font-size: 10px; padding: 0 5px;
  350. }
  351. ._tbl .brown-right-line {
  352. border-right: 1px solid;
  353. }
  354. ._tbl .date {
  355. padding-left: 5px;
  356. padding-right: 5px;
  357. }
  358. ._tbl .black-right-line {
  359. border-right: 1px solid;
  360. }`;
  361. var st = document.createTextNode(s);
  362. tblStyle.appendChild(st);
  363. head.appendChild(tblStyle);
  364.  
  365. // кнопка скрытия обновлений вручную
  366. var hideBtn = document.querySelector('#hideBtn');
  367. hideBtn.onclick = function() {
  368. hideBtn.style.display = 'none';
  369. // сразу сохраняем обновленные версии в память, чтобы при следующем обновлении не всплыли в таблице обновлений
  370. for(var i=0; i<saveToHideName.length; i++) {
  371. localStorage.setItem(saveToHideName[i], saveToHideVer[i]);
  372. }
  373. // скрываем таблицу с обновлениями и обнуляем счетчик
  374. _tbl.style.display = 'none';
  375. count = 0;
  376. _cnt.innerHTML = count;
  377. for(; _tbody.querySelectorAll('tr').length > 0;) {
  378. _tbl.deleteRow(1);
  379. }
  380. }
  381.  
  382. _span2.innerHTML = '<div id="ban"> <input id="showBanList" class="myBtn" type="button" value="Показать ЧС" /> <input id="clearBanList" class="myBtn" type="button" value="Очистить ЧС" disabled /> </div>' +
  383. `<table class="_tbl" id="ban_tbl" style="border-collapse: collapse; border: 0px; display: none;">
  384. <thead> <tr> <th class="brown-right-line">#</th> <th class="brown-right-line">Название</th> <th class="brown-right-line">Версия</th> <th class="brown-right-line">ID темы</th> <th title="Дата последнего обновления" class="date">Дата обновления</th> </tr> </thead>
  385. <tbody id="tbody2"> </tbody>
  386. </table>`;
  387. checkBan();
  388. function checkBan() {
  389. var tb = document.querySelector('#tbody2');
  390. if(savedIDs.length > 0 && savedIDs[0] !== '-1') {
  391. _span2.style.display = '';
  392. } else {
  393. _span2.style.display = 'none';
  394. }
  395. }
  396.  
  397. var showBanList = document.querySelector('#showBanList'),
  398. clearBanList = document.querySelector('#clearBanList'),
  399. ban_tbl = document.querySelector('#ban_tbl');
  400. showBanList.onclick = function() {
  401. if(ban_tbl.style.display == 'none') {
  402. ban_tbl.style.display = 'block';
  403. showBanList.value = 'Скрыть ЧС';
  404. clearBanList.disabled = false;
  405. clearBanList.style.textDecoration = '';
  406. } else {
  407. ban_tbl.style.display = 'none';
  408. showBanList.value = 'Показать ЧС';
  409. clearBanList.disabled = true;
  410. clearBanList.style.textDecoration = 'line-through';
  411. //clearBanList.style.setProperty("text-decoration", "line-through");
  412. }
  413. }
  414. clearBanList.style.textDecoration = 'line-through';
  415. clearBanList.onclick = function() {
  416. localStorage.setItem('savedIDs', '-1');
  417. checkSavedIDs();
  418. //log(savedIDs);
  419. }
  420.  
  421. // добавлению в таблицу скрытых приложений, их версии и id их темы
  422. var num = 0;
  423. function getBannedApps(app_name, ver, id, date) {
  424. num++;
  425. ver = ver.replace('v.', '');
  426. var _tbody2 = document.querySelector('#tbody2');
  427. var row =_tbody2.insertRow(-1),
  428. cell1 = row.insertCell(-1), // #
  429. cell2 = row.insertCell(-1), // Название
  430. cell3 = row.insertCell(-1), // Версия
  431. cell4 = row.insertCell(-1), // ID темы
  432. cell5 = row.insertCell(-1), // Дата обновления
  433. cell6 = row.insertCell(-1); // Скрыть
  434. row.className = 'myTr';
  435. cell1.className = 'black-right-line one';
  436. cell2.className = 'black-right-line';
  437. cell3.className = 'black-right-line';
  438. cell4.className = 'black-right-line';
  439. cell1.innerHTML = num;
  440. cell2.innerHTML = app_name;
  441. cell3.innerHTML = ver;
  442. cell4.innerHTML = id;
  443. cell5.innerHTML = date;
  444. cell6.innerHTML = '<input class="myBtn hidden" type="button" value="Удалить" style="display: none;">';
  445. }
  446.  
  447. // показ количества обновлений и вывод их в таблице
  448. function showUpdates(app_name, ver, date)
  449. {
  450. _tbl.style.display = 'block';
  451. n++;
  452. ver = ver.replace('v.', '');
  453. var row = _tbody.insertRow(-1),
  454. cell1 = row.insertCell(-1), // #
  455. cell2 = row.insertCell(-1), // Название
  456. cell3 = row.insertCell(-1), // Версия
  457. cell4 = row.insertCell(-1), // Дата обновления
  458. cell5 = row.insertCell(-1); // Скрыть
  459. row.className = 'myTr';
  460. cell1.className = 'black-right-line one';
  461. cell2.className = 'black-right-line';
  462. cell3.className = 'black-right-line';
  463. cell1.innerHTML = n; _cnt.innerHTML = count;
  464. cell2.innerHTML = app_name;
  465. cell3.innerHTML = ver;
  466. cell4.innerHTML = date;
  467. cell5.innerHTML = '<input class="myBtn hidden" type="button" value="Скрыть" style="display: none;">';
  468. }
  469.  
  470. function addEvent() {
  471. var myTr = document.querySelectorAll('.myTr');
  472. for(var i=0; i<myTr.length; i++) {
  473. myTr[i].addEventListener('mouseover', function showButton() {
  474. this.querySelector('.hidden').style.display = 'block';
  475. });
  476. myTr[i].addEventListener('mouseout', function hideButton() {
  477. this.querySelector('.hidden').style.display = 'none';
  478. });
  479. }
  480. }
  481.  
  482. function hideApp() {
  483. var hBut = document.querySelectorAll('.myBtn.hidden');
  484. for(var i=0; i<hBut.length; i++) {
  485. hBut[i].onclick = function() {
  486. var n = this.parentNode.parentNode.firstChild.innerHTML
  487. if(this.value === 'Скрыть') {
  488. var name = this.parentNode.parentNode.children[1].children[1].innerHTML,
  489. ver = this.parentNode.parentNode.children[2].innerHTML;
  490. localStorage.setItem(name, ver);
  491. // сброс # таблицы и удаление строк(и)
  492. _tbl.deleteRow(n);
  493. let num = _tbl.querySelectorAll('td.one');
  494. // если было скрыто последнее обновление, скрываем шапку таблицы и кнопку "Скрыть обновления"
  495. if(num.length === 0) {
  496. _tbl.style.display = 'none';
  497. hideBtn.style.display = 'none';
  498. }
  499. for(var j=0; j<num.length; j++) {
  500. num[j].innerHTML = j+1;
  501. }
  502. _cnt.innerHTML = j;
  503. } else {
  504. let id = this.parentNode.parentNode.children[3].innerHTML,
  505. arr = localStorage.getItem('savedIDs');
  506. arr = arr.split(',');
  507. for(let k=0; k<arr.length; k++) {
  508. if(id === arr[k]) {
  509. arr.splice(k, 1);
  510. }
  511. }
  512. if(arr.length !== 0) {
  513. localStorage.setItem('savedIDs', arr);
  514. } else {
  515. localStorage.setItem('savedIDs', '-1');
  516. }
  517.  
  518. // сброс # таблицы и удаление строк(и)
  519. ban_tbl.deleteRow(n);
  520. let num = ban_tbl.querySelectorAll('td.one');
  521. // если было скрыто последнее обновление, скрываем шапку таблицы и кнопку "Скрыть обновления"
  522. if(num.length === 0) {
  523. ban_tbl.style.display = 'none';
  524. var banBtns = document.querySelector('#ban');
  525. banBtns.style.display = 'none';
  526. }
  527. for(j=0; j<num.length; j++) {
  528. num[j].innerHTML = j+1;
  529. }
  530. }
  531. }
  532. }
  533. }
  534. //==========================================================================
  535. // мигание 'NEW' // уже неактуально
  536. /*function mig()
  537. {
  538. var isRed = true;
  539. var nw = document.querySelectorAll('.new');
  540. var dln = nw.length;
  541. if (dln !== 0)
  542. {
  543. var morganie = setInterval(function() {
  544. if (isRed)
  545. {
  546. for (i=0; i<dln; i++)
  547. {
  548. nw[i].style.color = 'blue';
  549. }
  550. isRed = false;
  551. }
  552. else
  553. {
  554. for (i=0; i<dln; i++)
  555. {
  556. nw[i].style.color = 'red';
  557. }
  558. isRed = true;
  559. }
  560. }, 300);
  561. }
  562. }*/
  563. }
  564. else
  565. {
  566. // Топики
  567. var post = document.querySelectorAll('.postdetails > center'),
  568. userLink = document.getElementsByClassName('normalname'),
  569. link = [], // собираем все ссылки на профили
  570. ulLength = userLink.length;
  571.  
  572. for (i=0; i<ulLength; i++)
  573. {
  574. getUserData(userLink[i].querySelector('a').getAttribute('href'), i);
  575. }
  576. //==========================================================================
  577. var data0, data1, data2, data3; // пол, город, дата рождения, местное время
  578. // создание области для новых данных
  579. var div = document.createElement('div');
  580. div.style.border = '1px solid lightblue';
  581. div.style.padding = '5px';
  582. div.id = 'myDiv';
  583.  
  584. // Стиль для новой области
  585. var style = document.createElement('style');
  586. style.type = 'text/css';
  587. var h = '#myDiv:hover {background: PaleTurquoise; color: blue; font-size: 10pt;}';
  588. var hover = document.createTextNode(h);
  589. style.appendChild(hover);
  590. //head = document.getElementsByTagName('head')[0];
  591. head.appendChild(style);
  592.  
  593. function getUserData(link, i) {
  594. var XHR = ("onload" in new XMLHttpRequest()) ? XMLHttpRequest : XDomainRequest;
  595. var xhr = new XHR();
  596. xhr.open('GET', link, true);
  597. xhr.send();
  598. xhr.onload = function()
  599. {
  600. if(this.readyState === 4)
  601. {
  602. if (this.status === 200)
  603. {
  604. var response = xhr.responseText;
  605. var parser = new DOMParser();
  606. var doc = parser.parseFromString(response, 'text/html');
  607. var main = doc.getElementsByClassName('info-list width1 black-link')[0];
  608. main.style.marginLeft = 0;
  609. main.style.paddingLeft = 0;
  610. main.style.display = 'block';
  611. main.style.listStyle = 'none';
  612. var t = main.querySelectorAll('li'),
  613. tt = '';
  614. for (var l=0; l<t.length; l++)
  615. {
  616. tt += t[l].innerHTML.replace(/<[^>]+>/g,'').replace(/(Город:)/, '$1 ').replace(/(юзера:)/, '$1 ').replace(/(рождения:)/, '$1 ') + '<br/>';
  617. }
  618. insertData(tt, i);
  619. }
  620. }
  621. };
  622. xhr.onerror = function() {
  623. log('error');
  624. alert('Ошибка');
  625. };
  626. xhr.onloadend = function(event) {
  627. //log('onloadend');
  628. totalKB += (event.loaded/1024); // подсчет загруженного траффика
  629. totalMB += (event.loaded/1024/1024);
  630. if(++l === ulLength) {
  631. log('Скачано XHR-запросами:', totalKB.toFixed(2), 'КБ |', totalMB.toFixed(2), 'МБ'); // вывод объема скачанного
  632. }
  633. };
  634. }
  635.  
  636. //==========================================================================
  637. function insertData(data0, i) {
  638. div.innerHTML = data0;
  639. post[i].appendChild(div.cloneNode(true));
  640. }
  641. }
  642. })();