// ==UserScript==
// @name Search Helper - MAL
// @namespace SearchHelper
// @version 18
// @description Quickly search for the anime/manga title on any websites of your choice.
// @author hacker09
// @include /^https:\/\/myanimelist\.net\/((anime|manga)(id=)?(\.php\?id=)?)(\/)?([\d]+)/
// @icon https://t3.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://myanimelist.net&size=64
// @run-at document-end
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
(function() {
'use strict';
var Addedname = []; //Creates a new blank array
var AddedFavIcon = []; //Creates a new blank array
var AddedsearchUrl = []; //Creates a new blank array
var RemovedLinksArray = []; //Creates a new blank array
const title = document.querySelector('meta[property="og:title"]').content.trim().match(/(?:Watch )?(.*)/)[1]; //Get the entry title
const titleEncoded = encodeURI(title); //Encode the entry title
const EntryType = location.pathname.split('/')[1]; //Store the Entry type
var AnimeorLiterature = '1_0'; //Define the variable to search for animes
const GFav = 'https://www.google.com/s2/favicons?domain='; //Creates a new variable
var Infoh2Elem = document.querySelectorAll("h2")[2]; //Save the Infomation h2 element to a variable If the entry is on the user list
GM_listValues().forEach(function(a) { //ForEach stored data on tampermonkey
if (a.match(/name|FavIcon|searchUrl/) === null) //If the stored data isn't an added name/favIcon/searchURL
{ //Starts the if condition
RemovedLinksArray.push('^' + a); //Add the user choice to hide a link on an array
} //Finishes the if condition
if (a.match('name') !== null) //If the stored data is an added name
{ //Starts the if condition
Addedname.push(GM_getValue(a)); //Add the new stored data to an array
} //Finishes the if condition
if (a.match('FavIcon') !== null) //If the stored data is an added favIcon
{ //Starts the if condition
AddedFavIcon.push(GM_getValue(a)); //Add the new stored data to an array
} //Finishes the if condition
if (a.match('searchUrl') !== null) //If the stored data is an added searchURL
{ //Starts the if condition
AddedsearchUrl.push(GM_getValue(a).split('addtitlehere')[0] + titleEncoded + GM_getValue(a).split('addtitlehere')[1]); //Add the new stored data to an array
} //Finishes the if condition
}); //Add all removed links on tampermonkey to the array
const RemovedLinksArrayRegex = new RegExp(RemovedLinksArray.join('$|')); //Create a new variable and regex containing all the removed links saved on tampermonkey and replace the , separator with the or $| regex symbols
if (EntryType === 'manga') //If the entry type is manga
{ //Start the if conditon
AnimeorLiterature = '3_0'; //Define the variable to search for Literatures
} //Finishes the if conditon
const names = ['Crunchyroll', 'AnimesHouse', 'Funimation', 'AnimeSpank', 'AnimesOnline.cz', 'AnimeFan', 'AnimesFire', 'AnimesonlineX', 'AnimesVision', 'Yayanimes', 'Goyabu', 'Anbient', '9Anime', 'Nyaa', 'Gogoanime', 'AnimeFreak', 'Anime-Freak', 'AnimeFreak1', 'Youtube', 'Jkanime', 'AnimeFLV', 'AnimeFlix', 'AniList', 'aniDB', 'Kitsu', 'Anime-Planet', 'AnimeNewsNetwork', 'AnimeOwl', 'AniSearch', 'Annict', 'Netflix', 'Hidive', 'LiveChart', 'Notify', 'Proxer', 'Shikimori', 'Simkl', 'Trakt', 'TurkAnime', 'Doujinshi', 'LNDB', 'Mangadex', 'Mangaupdates', 'Novel Updates', 'VIZ', 'MangaPlus']; //Add the default website names to an array
const Allnames = Addedname.concat(names); //Add the default and added website names to an array
const searchUrl = AddedsearchUrl.concat([document.querySelector("a.broadcast-item[href*='crunchyroll.com/series']") ? document.querySelector("a.broadcast-item[href*='crunchyroll.com/series']").href : 'http://www.crunchyroll.com/search?q=' + titleEncoded, 'https://animeshouse.net/?s=' + titleEncoded, document.querySelector("a.broadcast-item[href*='funimation.com/shows']") ? document.querySelector("a.broadcast-item[href*='funimation.com/shows']").href : 'https://www.funimation.com/search/?q=' + titleEncoded, 'https://animespank.com/?s=' + titleEncoded, 'https://www.animesonline.cz/busca/?search_query=' + titleEncoded, 'https://animefan.cc/?s=' + titleEncoded, 'https://www.google.com/search?q=' + titleEncoded + '+site:https://animefire.net', 'https://animesonlinex.org/?s=' + titleEncoded, 'https://animesvision.biz/search?nome=' + titleEncoded, 'https://yayanimes.net/?s=' + titleEncoded, 'https://goyabu.com/?s=' + titleEncoded, 'https://www.anbient.com/search?search_api_views_fulltext=' + titleEncoded, 'https://9anime.id', 'https://nyaa.si/?f=0&c=' + AnimeorLiterature + '&q=' + titleEncoded, 'https://gogoanime.gg/search.html?keyword=' + titleEncoded, 'https://animefreak.site/search?keyword=' + titleEncoded, 'https://anime-freak.su/?s=' + titleEncoded, 'https://animefreak1.com/search/?keyword=' + titleEncoded, 'https://www.youtube.com/results?search_query=' + titleEncoded, 'https://jkanime.net/buscar/' + titleEncoded + '/1/', 'https://animeflv.net/browse?q=' + titleEncoded, 'https://animeflix.nl/search/?keyword=' + titleEncoded, 'https://anilist.co/search/' + EntryType + '?sort=SEARCH_MATCH&search=' + titleEncoded, 'https://anidb.net/anime/?do.search=1&adb.search=' + titleEncoded, 'https://kitsu.io/' + EntryType + '?text=' + titleEncoded, 'https://www.anime-planet.com/search.php?search_type=' + EntryType + '&search=' + titleEncoded, 'https://www.animenewsnetwork.com/encyclopedia/search/name?only=' + EntryType + '&q=' + titleEncoded, 'https://animeowl.net/?s=' + titleEncoded, 'https://www.anisearch.com/' + EntryType + '/index?text=' + titleEncoded, 'https://annict.com/search?q=' + titleEncoded, 'https://www.netflix.com/search?q=' + titleEncoded, 'http://www.hidive.com/search?q=' + titleEncoded, 'https://www.livechart.me/search?q=' + titleEncoded, 'https://notify.moe/search/' + titleEncoded, 'https://proxer.me/search?s=search&name=' + titleEncoded + '&typ=all-' + EntryType + '&tags=¬ags=#top', 'https://shikimori.org/' + EntryType + 's?search=' + titleEncoded, 'https://simkl.com/search/?type=anime&q=' + titleEncoded, 'https://trakt.tv/search?query=' + titleEncoded, 'https://www.google.com/search?q=' + titleEncoded + '+site:turkanime.tv/anime/ OR site:turkanime.net/anime/', 'https://www.doujinshi.org/search/simple/?T=objects&sn=' + titleEncoded, 'http://lndb.info/search?text=' + titleEncoded, 'https://mangadex.org/titles?q=' + titleEncoded, 'https://www.mangaupdates.com/series.html?search=' + titleEncoded, 'https://www.novelupdates.com/?s=' + titleEncoded, 'https://www.viz.com/search?search=' + titleEncoded, 'https://mangaplus.shueisha.co.jp/search_result?keyword=' + titleEncoded]); //Add the default and added website search urls to an array
const FavIcon = AddedFavIcon.concat([GFav + 'www.crunchyroll.com', GFav + 'https://animeshouse.net', GFav + 'https://www.funimation.com', GFav + 'https://animespank.com', GFav + 'https://www.animesonline.cz', GFav + 'https://animefan.cc', GFav + 'animefire.net', GFav + 'animesonlinex.org', 'https://i.imgur.com/szbQyHN.png', 'https://i.imgur.com/yrUmBG6.png', 'https://i.imgur.com/OhTIrFM.png', GFav + 'https://www.anbient.com/', 'https://i.imgur.com/ZzQVRHu.png', GFav + 'nyaa.si', GFav + 'gogoanime.gg', GFav + 'animefreak.site', GFav + 'anime-freak.su', GFav + 'animefreak1.com', GFav + 'www.youtube.com', GFav + 'jkanime.net', GFav + 'animeflv.net', GFav + 'https://animeflix.nl', GFav + 'anilist.co', GFav + 'anidb.net', GFav + 'kitsu.io', GFav + 'anime-planet.com', GFav + 'animenewsnetwork.com', GFav + 'https://animeowl.net', GFav + 'anisearch.com', GFav + 'annict.com', GFav + 'www.netflix.com', GFav + 'www.hidive.com', GFav + 'https://livechart.me', GFav + 'notify.moe', GFav + 'https://proxer.me', GFav + 'https://shikimori.org', GFav + 'simkl.com', GFav + 'trakt.tv', GFav + 'https://www.turkanime.net', GFav + 'https://www.doujinshi.org', GFav + 'lndb.info', GFav + 'mangadex.org', 'https://i.imgur.com/JSmTsdc.png', GFav + 'www.novelupdates.com', GFav + 'www.viz.com', 'https://i.imgur.com/kKkT7BV.png']); //Add the default and added website fav icons to an array
if (document.querySelectorAll("h2")[2].innerText !== 'Information') //If the entry is not on the user list
{ //Starts the if condition
Infoh2Elem = document.querySelectorAll("h2")[1]; //Save the Infomation h2 element to a variable
} //Finishes the if condition
Infoh2Elem.insertAdjacentHTML('beforebegin', `<h2 style="cursor: pointer;" class="${document.querySelector("h2").className} MAL_SearchHelper">Search</h2><br><div class="MAL_SearchHelperBTN" style="cursor: pointer; color: #1d439b;">[Show]</div><div class="mal_links" style="display: none;"></div><br>`); //Add the [Show] button on the page
Allnames.forEach(function(name, i) { //For each website name
if (name.match(RemovedLinksArrayRegex) === null || RemovedLinksArrayRegex.toLocaleString() === '/(?:)/') //If the website doesn't match an removed link,or if there are 0 links removed
{ //Starts the if condition
document.querySelector(".mal_links").insertAdjacentHTML('beforeend', `<div id="${name}+Search" style="padding: 1px 0;"><a target="_blank" title="Search on ${name}" href="${searchUrl[i]}"><img style="position: relative; top: 4px;" src="${FavIcon[i]}" /> ${name}</a><span onmouseout="this.parentElement.style.backgroundColor = ''" onmouseover="this.parentElement.style.backgroundColor = '#d6e3ff'" title="Remove ${name}?" id="${name}" class="remove-link" style="z-index: 999999; position: sticky; left: calc(100% - 4%); line-height: 2;cursor: pointer;color: grey;">X</span></div>`);
} //Finishes the if condition
}); //Finishes the foreach condition to add the html to open and search for the entry title or to remove the website of the search list
document.querySelector(".MAL_SearchHelperBTN").onclick = function() { //When the Search button is clicked
document.querySelector("#synopsisBlock") !== null ? document.querySelector("#synopsisBlock").style.maxHeight = 'fit-content' : ''; //Show all search links
const element = document.querySelector(".mal_links"); //Save the list of links element in a variable
if (element.style.display === 'none') { //If the Search list is hidden
element.style.display = 'block'; //Show the Search List
this.innerText = "[Hide]"; //Change the Show Search List text to [Hide]
} else { //If the Search list is being shown
element.style.display = 'none'; //Hide the Search List
this.innerText = "[Show]"; //Change the Hide Search List text to [Show]
} //Finishes the else condition
}; //Finishes the onclick event listener
document.querySelector(".MAL_SearchHelper").onclick = function() { //When the Search txt is clicked
const WebsiteName = prompt("*You CAN'T click on Cancel neither leave the field blank!\nPlease enter the website name."); //Temporarily save the website name
GM_setValue("name" + WebsiteName, WebsiteName); //Ask the user to enter the website name and permanently save it
GM_setValue("FavIcon" + WebsiteName, prompt("\n*Optional\nPlease enter the website FavIcon URL.\n*If you don't know the website FavIcon URL click on ok!", "https://www.google.com/s2/favicons?domain=tesgooglet.com")); //Ask the user to enter the website FavIcon
GM_setValue("searchUrl" + WebsiteName, prompt("Please enter the website search URL.\n*Add the text addtitlehere in the place you want the script to add the entry title on the link.\n*Example: https://goyabu.com/?s=addtitlehere")); //Ask the user to enter the website search URL
}; //Finishes the onclick event listener
document.querySelector("#\\39 Anime\\+Search").onclick = function(e) { //When the 9anime search btn is clicked
e.preventDefault(); //Prevent the default context menu from being opened
navigator.clipboard.writeText(document.querySelector("[itemprop*='name']").innerText.split('\n')[0]); //Copy the entry romaji title text
setTimeout(() => { //After the entry title was copied
window.open('https://9anime.id', '_blank'); //Open the 9anime website on a new tab
}, 0); //Open the 9anime website on a new tab
}; //Finishes the onclick event listener
document.querySelectorAll("span.remove-link").forEach(function(el) { //For each remove button
el.onclick = function() //Add a click event listener to the remove btn
{ //Starts the onclick function
this.parentElement.remove(); //Remove the correspondent website of the search list
if (names.includes(this.id.split('+')[0]) === true) //If the website removed as a default website
{ //Starts the if condition
GM_setValue(el.id.split('+')[0], "RemovedSite"); //Save the user option
} //Finishes the if condition
else //If the website removed was added by the user
{ //Starts the else condition
GM_listValues().forEach(function(a) { //ForEach stored data on tampermonkey
if (a.match(el.id.split('+')[0]) !== null) //If the stored data that has the specified name/favIcon/searchURL website name
{ //Starts the if condition
GM_deleteValue(a); //Erase the stored name/favIcon/searchURL for the specific website
} //Finishes the if condition
}); //Finishes the for each condition
} //Finishes the else condition
}; //Finishes the onclick function
}); //Finishes the for each condition
})();