Animator.ru – True Links [Ath]

Improves navigation on Animator.ru: displays long lists without pagination; replaces script links (JavaScript) with real ones (href), so they can be opened in a new tab, copied, etc.

  1. // ==UserScript==
  2. // @name Animator.ru – True Links [Ath]
  3. // @name:ru Animator.ru – Настоящие Ссылки [Ath]
  4. // @name:uk Animator.ru – Справжні Посилання [Ath]
  5. // @name:be Animator.ru – Сапраўдныя Спасылкі [Ath]
  6. // @name:bg Animator.ru – Истински Връзки [Ath]
  7. // @name:tt Animator.ru – Чын Сылтамалар [Ath]
  8. // @name:sl Animator.ru – Prave Povezave [Ath]
  9. // @name:sr Animator.ru – Pravi Linkovi [Ath]
  10. // @name:ka Animator.ru – ნამდვილი ბმულები [Ath]
  11. // @description Improves navigation on Animator.ru: displays long lists without pagination; replaces script links (JavaScript) with real ones (href), so they can be opened in a new tab, copied, etc.
  12. // @description:ru Улучшает навигацию на Animator.ru: отображает длинные списки целиком без разбиения на страницы; заменяет скриптовые ссылки (JavaScript) на настоящие (href), чтобы их можно было открывать в новой вкладке, копировать адрес и т.п.
  13. // @description:uk Покращує навігацію на Animator.ru: відображає довгі списки повністю без розбиття на сторінки; замінює скриптові посилання (JavaScript) на справжні (href), щоб їх можна було відкривати у новій вкладці, копіювати адресу тощо.
  14. // @description:be Паляпшае навігацыю на Animator.ru: паказвае доўгія спісы цалкам без падзелу на старонкі; замяняе скрыптовыя спасылкі (JavaScript) на сапраўдныя (href), каб іх можна было адкрываць у новай укладцы, капіяваць адрас і г.д.
  15. // @description:bg Подобрява навигацията на Animator.ru: показва дълги списъци без разделяне на страници; заменя скриптовите връзки (JavaScript) с истински (href), така че те да могат да се отварят в нов таб, да се копират и т.н.
  16. // @description:tt Animator.ru сайтында навигацияне яхшырта: озын исемлекләрне битләргә бүлмичә күрсәтә; скрипт сылтамаларын (JavaScript) чын сылтамаларга (href) алыштыра, шулай итеп аларны яңа тәрәзәдә ачып, адресын күчереп алырга һ.б. мөмкинлек бирә.
  17. // @description:sl Izboljša navigacijo na Animator.ru: prikazuje dolge sezname brez razdelitve na strani; nadomešča skriptne povezave (JavaScript) z resničnimi (href), tako da jih lahko odpremo v novem zavihku, kopiramo naslov itd.
  18. // @description:sr Poboljšava navigaciju na Animator.ru: prikazuje duge liste bez paginacije; zamenjuje skript linkove (JavaScript) sa pravim (href), tako da ih je moguće otvoriti u novom tabu, kopirati adresu itd.
  19. // @description:ka ანიმატორის ნავიგაციას ამეტებს Animator.ru-ზე: აჩვენებს გრძელ სიას გვერდების გარეშე; შეცვლის სკრიპტის ბმულებს (JavaScript) ნამდვილებით (href), რათა მათ შეიძლება ახალ ჩანართში გახსნა, მისამართის ასლი და ა.შ.
  20. // @namespace athari
  21. // @author Athari (https://github.com/Athari)
  22. // @copyright © Prokhorov ‘Athari’ Alexander, 2024–2025
  23. // @license MIT
  24. // @homepageURL https://github.com/Athari/AthariUserJS
  25. // @supportURL https://github.com/Athari/AthariUserJS/issues
  26. // @version 1.0.0
  27. // @icon https://www.google.com/s2/favicons?sz=64&domain=animator.ru
  28. // @match https://*.animator.ru/*
  29. // @grant unsafeWindow
  30. // @run-at document-end
  31. // @require https://cdn.jsdelivr.net/npm/@athari/monkeyutils@0.3.1/monkeyutils.u.min.js
  32. // @tag athari
  33. // ==/UserScript==
  34.  
  35. (async () => {
  36. 'use strict'
  37.  
  38. const { urlSearch, adjustLocationSearch, attempt, els } =
  39. //require("../@athari-monkeyutils/monkeyutils.u"); // TODO
  40. athari.monkeyutils;
  41.  
  42. const el = els(document, {
  43. navPaginationLast: ".mynavig div:last-child",
  44. javascriptLinks: "[onclick]",
  45. });
  46.  
  47. el.tag.head.insertAdjacentHTML('beforeEnd', /*html*/`
  48. <style>
  49. body {
  50. background: #aaa;
  51. }
  52. .ath-link {
  53. font-size: 14px;
  54. margin: 0 0 3px 0;
  55. text-decoration: none;
  56. &:hover {
  57. text-decoration: underline;
  58. }
  59. }
  60. </style>`);
  61.  
  62. const nPages = el.navPaginationLast?.id.substring(2) ?? 0;
  63. if (nPages > 0) {
  64. await attempt("load pagination", async () => {
  65. const win1251Decoder = new TextDecoder('windows-1251');
  66. const tableSelector = [ ".FilmDiv", "table[style*='rgb(33,12,99)']", "table:has(> tbody > script ~ tr)" ]
  67. .map(sel => ({ sel, el: document.querySelector(sel) }))
  68. .filter(i => i.el != null)[0]?.sel;
  69. console.debug({ tableSelector });
  70. const docs = [];
  71. unsafeWindow.docs = docs;
  72. const rows = await Promise.all(
  73. [...Array(+nPages).keys()].map(async (iPage) => {
  74. const response = await fetch(adjustLocationSearch({ cPage: iPage + 1 }));
  75. const doc = new DOMParser().parseFromString(win1251Decoder.decode(await response.arrayBuffer()), 'text/html');
  76. docs.push(doc);
  77. return [...doc.querySelectorAll(`${tableSelector} script ~ tr`)].slice(1).map(r => r.outerHTML).join("");
  78. })
  79. );
  80. document.querySelector(tableSelector)?.tBodies[0].insertAdjacentHTML('beforeEnd', rows.join(""));
  81. console.debug("docs", docs);
  82. });
  83. }
  84.  
  85. const search = urlSearch(location);
  86. const langPrefix = search.ver == 'eng' ? "ver=eng&" : "";
  87. const funs = {
  88. showNews: id => `/?${langPrefix}p=show_news&nid=${id}`,
  89. showNewsCat: (t, p) => `/?${langPrefix}p=news&type=${t}&cPage=${p}`,
  90. showFilm: id => `/db/?${langPrefix}p=show_film&fid=${id}`,
  91. showPerson: id => `/db/?${langPrefix}p=show_person&pid=${id}`,
  92. showStudia: id => `/db/?${langPrefix}p=show_studia&sid=${id}`,
  93. showVSource: id => `/db/?${langPrefix}p=vsource&id=${id}`,
  94. snb_click: id => adjustLocationSearch({ sp: id }),
  95. ReGroupFilms: b => `/db/?${langPrefix}p=show_person&pid=${search.pid}&JoinFilmsInFilmography=${b}`,
  96. };
  97. for (let [ elLink, js ] of el.all.javascriptLinks.map(el => [ el, el.getAttribute('onclick') ])) {
  98. const [, fun, ids] = js.match(/([\w_]+)\('?(\d+(,\d+)*)'?\)/) ?? [];
  99. let href = funs[fun]?.(...ids.split(","));
  100. if (!href)
  101. [,, href] = js.match(/(?:self\.)?location\.href\s*=\s*(['"])([^'"]+)\1/) ?? [];
  102. if (href) {
  103. elLink.outerHTML = /*html*/`<a href="${href}" class="ath-link">${elLink.innerText}</a>`;
  104. elLink.removeAttribute('onclick');
  105. } else {
  106. console.warn("Failed to convert onclick to href", elLink, js);
  107. }
  108. }
  109. })();