Kinopoisk - FlicksBar Button for Google

Добавляет кнопку "Flicksbar" с подменой ссылки kinopoisk.ru на sspoisk.ru в раздел "Смотреть фильм"

  1. // ==UserScript==
  2. // @name Kinopoisk - FlicksBar Button for Google
  3. // @namespace https://t.me/flicksbar
  4. // @version 1.0.2
  5. // @description Добавляет кнопку "Flicksbar" с подменой ссылки kinopoisk.ru на sspoisk.ru в раздел "Смотреть фильм"
  6. // @author Devitp001
  7. // @match https://www.google.com/search*
  8. // @icon https://www.kinopoisk.ru/favicon.ico
  9. // @icon64 https://www.kinopoisk.ru/favicon.ico
  10. // @grant none
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14.  
  15. (function () {
  16. 'use strict';
  17.  
  18. if (!location.hostname.includes('google')) return;
  19.  
  20. function log(message) {
  21. console.log(`[FlicksBar]: ${message}`);
  22. }
  23.  
  24. // Поиск кнопки "Хочу посмотреть"
  25. function findWishlistButton() {
  26. return Array.from(document.querySelectorAll('*'))
  27. .flatMap(el => {
  28. if (el.shadowRoot) {
  29. return Array.from(
  30. el.shadowRoot.querySelectorAll('[aria-label=" Хочу посмотреть "]')
  31. );
  32. }
  33. return [];
  34. })
  35. .concat(
  36. Array.from(document.querySelectorAll('[aria-label=" Хочу посмотреть "]'))
  37. );
  38. }
  39.  
  40. // Создание кнопки "F" с точной структурой
  41. function createFlicksBarButton(referenceElement, redirectURL) {
  42. const outerDiv = document.createElement('a');
  43. outerDiv.href = redirectURL;
  44. outerDiv.target = '_blank';
  45. outerDiv.rel = 'noopener';
  46. outerDiv.role = 'button';
  47. outerDiv.tabIndex = '0';
  48.  
  49. // Копируем классы из оригинальной кнопки
  50. const originalClassList = referenceElement.classList;
  51. outerDiv.className = [...originalClassList].join(' ');
  52.  
  53. // Внутренний контейнер VDgVie...
  54. const innerContainer = document.createElement('div');
  55. innerContainer.className = 'VDgVie btku5b fCrZyc NQYJvc qVhvac zqrO0 sLl7de OJeuxf';
  56.  
  57. // Обёртка niO4u
  58. const niO4u = document.createElement('div');
  59. niO4u.className = 'niO4u';
  60.  
  61. // kHtcsd
  62. const kHtcsd = document.createElement('div');
  63. kHtcsd.className = 'kHtcsd';
  64.  
  65. // d3o3Ad gJdC8e
  66. const iconWrapper = document.createElement('span');
  67. iconWrapper.className = 'd3o3Ad gJdC8e';
  68.  
  69. // RUoEBe... (иконка)
  70. const svgContainer = document.createElement('span');
  71. svgContainer.className = '1RUoEBe K5Jxee z1asCe DoJQd';
  72. svgContainer.style.height = '20px';
  73. svgContainer.style.lineHeight = '20px';
  74. svgContainer.style.width = '20px';
  75.  
  76. // SVG
  77. const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  78. svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
  79. svg.setAttribute('width', '24');
  80. svg.setAttribute('height', '24');
  81. svg.setAttribute('viewBox', '0 0 24 24');
  82. svg.innerHTML = `<path d="M3 3 h18 v4 H6 v6 h14 v4 H6 v10 H2 zm0"/>`;
  83.  
  84.  
  85.  
  86.  
  87. svgContainer.appendChild(svg);
  88. iconWrapper.appendChild(svgContainer);
  89.  
  90. kHtcsd.appendChild(iconWrapper);
  91. niO4u.appendChild(kHtcsd);
  92.  
  93. // Текстовая часть
  94. const textContainer = document.createElement('div');
  95. textContainer.className = 'QuU3Wb sjVJQd';
  96. textContainer.setAttribute('aria-hidden', 'true');
  97. textContainer.textContent = ' FlicksBar ';
  98.  
  99. //const textDiv = document.createElement('div');
  100. //textDiv.setAttribute('aria-hidden', 'true');
  101. //textDiv.textContent = ' FlicksBar ';
  102.  
  103. //textContainer.appendChild(textDiv);
  104.  
  105. // Компоновка
  106. innerContainer.appendChild(niO4u);
  107. innerContainer.appendChild(textContainer);
  108. outerDiv.appendChild(innerContainer);
  109.  
  110. return outerDiv;
  111. }
  112.  
  113. // Поиск ссылки на Кинопоиск
  114. function findKinopoiskLink() {
  115. return Array.from(document.querySelectorAll('a'))
  116. .filter(link => {
  117. const href = link.href || '';
  118. return (
  119. href.startsWith('https://www.kinopoisk.ru/film/') ||
  120. href.startsWith('https://www.kinopoisk.ru/series/')
  121. );
  122. })[0];
  123. }
  124.  
  125. // Подмена ссылки kinopoisk.ru на sspoisk.ru
  126. function getRedirectURL(kinopoiskLink) {
  127. if (!kinopoiskLink) return null;
  128.  
  129. const kinopoiskHref = kinopoiskLink.href;
  130. const sspoiskHref = kinopoiskHref.replace('kinopoisk.ru', 'sspoisk.ru');
  131.  
  132. // Вариант 1: Переход напрямую на sspoisk.ru
  133. return sspoiskHref;
  134.  
  135. // Вариант 2: С редиректом через flicks.bar (если нужно)
  136. }
  137.  
  138. // Вставка кнопки "F"
  139. function injectFButtonBeforeWishlist(wishlistButton) {
  140. const container = wishlistButton.closest('div, span')?.parentElement;
  141. if (!container) return;
  142.  
  143. const existing = container.querySelector('a[href*="sspoisk.ru"]');
  144. if (existing) return;
  145.  
  146. // Найдём ссылку на Кинопоиск
  147. const kinopoiskLink = findKinopoiskLink();
  148. const redirectURL = getRedirectURL(kinopoiskLink);
  149.  
  150. if (!redirectURL) {
  151. log('Не удалось найти ссылку на Кинопоиск');
  152. return;
  153. }
  154.  
  155. const fButton = createFlicksBarButton(wishlistButton, redirectURL);
  156. container.insertBefore(fButton, wishlistButton);
  157. log('Добавлена кнопка "F" перед "Хочу посмотреть"');
  158. }
  159.  
  160. // Наблюдатель за изменениями DOM
  161. const observer = new MutationObserver((mutationsList) => {
  162. for (const mutation of mutationsList) {
  163. if (mutation.type === 'childList') {
  164. const wishlistButton = findWishlistButton()[0];
  165. if (wishlistButton) {
  166. injectFButtonBeforeWishlist(wishlistButton);
  167. }
  168. }
  169. }
  170. });
  171.  
  172. observer.observe(document.body, { childList: true, subtree: true });
  173.  
  174. // Первоначальный запуск
  175. const wishlistButton = findWishlistButton()[0];
  176. if (wishlistButton) {
  177. injectFButtonBeforeWishlist(wishlistButton);
  178. }
  179. })();