Find on Nyaa

Will open nyaa on a new window and search for the anime title

目前為 2022-10-02 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Find on Nyaa
// @namespace    MALFindNya
// @version      2.2
// @description  Will open nyaa on a new window and search for the anime title
// @author       Samu
// @match        https://myanimelist.net/anime/*
// @match        https://myanimelist.net/anime.php?id=*
// @match        https://anilist.co/*
// @match        https://kitsu.io/*
// @match        https://www.anime-planet.com/*
// @grant        none
// ==/UserScript==

/**
  icon source
  https://icons8.com/icon/82838/external-link
  https://ezgif.com/image-to-datauri
**/

//** SETTINGS **//
let sortBy = "seeders";                       // "comments", "size", "id", "seeders", "leechers", or "downloads"
let filter = "0";                             // 0 = No Filter | 1 = No remakes | 2 = Trusted Only
let category = "AnimeEnglishTranslated";      // Check values below
let favoriteGroups = ["Judas", "Erai-raws"];  // List is ordered, favorite should be first
let searchPrefix = "";
let searchSufix = "";
//** END OF SETTINGS **//

const cat = {
  Allcategories: "0_0",
  Anime: "1_0",
  AnimeMusicVideo: "1_1",
  AnimeEnglishTranslated: "1_2",
  AnimeNonEnglishTranslated: "1_3",
  Raw: "1_4",
  Audio: "2_0",
  Lossless: "2_1",
  Lossy: "2_2",
  Literature: "3_0",
  LiteratureEnglishTranslated: "3_1",
  LiteratureNonEnglishTranslated: "3_2",
  LiteratureRaw: "3_3",
  LiveAction: "4_0",
  LiveActionEnglishTranslated: "4_1",
  IdolPromotionalVideo: "4_2",
  LiveActionNonEnglishTranslated: "4_3",
  LiveActionRaw: "4_4",
  Pictures: "5_0",
  Graphics: "5_1",
  Photos: "5_2",
  Software: "6_0",
  Applications: "6_1",
  Games: "6_2",
};

const buttonId = "FindOnNyaaButtonId";

(function() {
  'use strict';

  let pushState = history.pushState;
  let replaceState = history.replaceState;

  history.pushState = function() {
      pushState.apply(history, arguments);
      window.dispatchEvent(new Event('pushstate'));
      window.dispatchEvent(new Event('locationchange'));
  };

  history.replaceState = function() {
      replaceState.apply(history, arguments);
      window.dispatchEvent(new Event('replacestate'));
      window.dispatchEvent(new Event('locationchange'));
  };

  window.addEventListener('popstate', function() {
      window.dispatchEvent(new Event('locationchange'))
  });

  let host = window.location.host;
  let path = window.location.pathname;

  window.addEventListener('locationchange', function() {
    path = window.location.pathname;
    lookForTitleElement(host, path);
  });

  lookForTitleElement(host, path);

})();

function lookForTitleElement(host, path) {
  if (host === "myanimelist.net") {
    waitForElm('.title-name').then((elm) => init(elm));
  } else if (host === "anilist.co" && path.startsWith("/anime/")) {
    waitForElm('.page-content .header .content > h1').then((elm) => init(elm));
  } else if (host === "kitsu.io" && path.startsWith("/anime/")) {
    waitForElm('.media--title h3').then((elm) => init(elm));
  } else if (host === "www.anime-planet.com" && path.startsWith("/anime/")) {
    waitForElm('#siteContainer h1').then((elm) => init(elm));
  } else {
    let nyaaButton = document.getElementById(buttonId);
    if (nyaaButton != null) {
      nyaaButton.parentElement.removeChild(nyaaButton);
    }
  }
}

function init(element) {
  let url = createUrl(element);
  let nyaaButton = document.getElementById(buttonId);
  if (nyaaButton == null) {
    nyaaButton = createButton(url);
    element.appendChild(nyaaButton);
  } else {
    nyaaButton.setAttribute("href", url);
  }
}

function createButton(url) {
  let button = document.createElement("a");
  button.id = buttonId;
  button.innerHTML = "";
  button.setAttribute("href", url);
  button.setAttribute("target", "_blank");
  button.setAttribute("rel", "noopener");
  button.setAttribute("title", "Search on Nyaa");
  button.setAttribute("style", "margin-left: 10px;height: 10px;width: 10px;background-size: cover;display: inline-block;transform: scale(1.8);vertical-align: top;margin-top: 7px;");
  button.style.backgroundImage = "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFnSURBVGhD7ZlLSgNRFESzDp3qSPfjdlyOgjsTxM9U0HsggWt7k3716mln8A4chM61qjrT7CaTyeSsuQ6fwvfwq9Ml1U2LMlfhS1iFKS6pblqU4ZuvglSXVDctynyEVZDqkuqmRRk7QOQu/AyXvQdl7ACBtfEoYwc0Uo2vXkbGDmjg2Hie52coYwescGo85OcoYwecYG085M9Qxg44Qst4yJ+jjB1Q0Doe8g3K2AELlPGQ71DGDkio4yHfoowdsKdn/BByIfaw2XjIpaiy6XjIxaiw+XjI5djKqPH5/1GmJ2DkN58zUEYNGDkecg7KKAGjx0POQpnWgNtw9HjIeSijBNyHh7sR4yF3o4wawEuMGg9q/y96Am72f0fQ0/8DO8DE7rcDTOx+O8DE7rcDTOx+O8DE7rcDTOx+5zeB0b6FMo9hFbaFbJG5CJ/DKvA/ZQNburgMefvXsAr/S+l8CNkwmUwmZ8lu9w0a6EAybIGM4AAAAABJRU5ErkJggg==)";
  return button;
}

function createUrl(element) {
  let textFragment = ":~:text=" + favoriteGroups.join("&text=");
  let title = element.textContent.trim().replace(/[^a-zA-Z0-9]+/g, "+");
  let query = [searchPrefix, title.trim(), searchSufix].join(" ").trim();
  let queryURI = encodeURI(query);
  let baseUrl = "https://nyaa.si/";
  let path = `?f=${filter}&c=${cat[category]}&s=${sortBy}&o=desc&q=${queryURI}`;
  return baseUrl + path + "#" + textFragment;
}

function waitForElm(selector) {
  return new Promise(resolve => {
    if (document.querySelector(selector)) {
      return resolve(document.querySelector(selector));
    }

    const observer = new MutationObserver(mutations => {
      if (document.querySelector(selector)) {
        resolve(document.querySelector(selector));
        observer.disconnect();
      }
    });

    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  });
}