Greasy Fork is available in English.
Labels dubbed titles on MyAnimeList.net and adds dub only filtering to search, seasonal and top anime pages.
ของเมื่อวันที่
// ==UserScript==// @name MyAnimeList Label English Dubs// @namespace https://github.com/MAL-Dubs// @version 0.9.01// @description Labels dubbed titles on MyAnimeList.net and adds dub only filtering to search, seasonal and top anime pages.// @author MAL Dubs// @supportURL https://github.com/MAL-Dubs/MAL-Dubs/issues// @match http://myanimelist.net/*// @match https://myanimelist.net/*// @match http://*.myanimelist.net/*// @match https://*.myanimelist.net/*// @iconURL https://raw.githubusercontent.com/MAL-Dubs/MAL-Dubs/main/images/icon.png// @license GPL version 2 or any later version; http://www.gnu.org/licenses/gpl-2.0.txt// @resource CSS https://raw.githubusercontent.com/MAL-Dubs/MAL-Dubs/main/css/style.css// @grant GM_xmlhttpRequest// @grant GM_addStyle// @grant GM_getResourceText// @connect githubusercontent.com// @connect github.com// @run-at document-end// @noframes// ==/UserScript==(function() {const dubbedLinks = document.querySelectorAll("p.title-text>a,content-r###lt .information>a:first-child,.list>.information>a:first-child,table.anime_detail_related_anime a[href^='/anime'],p.data a.title,td.data.title a:first-child,.list td:nth-child(2)>a.hoverinfo_trigger,#content>table>tbody>tr>td>table>tbody>tr>td.borderClass>a[href*='myanimelist.net/anime/'],#content>div>div>table>tbody>tr>td>a[href*='/anime'],#content>table>tbody>tr>td:nth-child(2)>div.js-scrollfix-bottom-rel>div>table>tbody>tr>td:nth-child(2)>div:nth-child(2)>a:nth-child(1),.news-container h2 a[href*='/anime/'],li.ranking-unit>div>h3>a,tr.ranking-list>td:nth-child(2)>div>div>h3>a,div.borderClass>a,#content>table>tbody>tr>td:nth-child(1)>a:nth-child(1),[id^='#revAreaItemTrigger'],.news-container a[href^='https://myanimelist.net/anime/'],.animeography>.title>a,#content>div:nth-child(3)>a"),dubbedRecs = document.querySelectorAll("div#anime_recommendation>div.anime-slide-outer>.anime-slide>li.btn-anime>a.link:not([href*='suggestion'])"),dubbedThumbs = "div.auto-recommendations>div.items>a.item,div.recommendations div.items>a.item,div#widget-seasonal-video li.btn-anime>a.link,div#anime_recommendation li.btn-anime.auto>a.link,.js-seasonal-anime>.image>a:nth-child(1)",rgx = /^(https?:\/\/myanimelist\.net)?\/?anime\/(\d+)\/?.*/,recrgx = /^(https?:\/\/myanimelist\.net)?\/recommendations\/anime\/(\d+\-\d+)\/?.*/,filteruri = /.*\/(((anime\.php\?(?!id).+|topanime\.php.*))|anime\/(genre|producer|season)\/?.*)/;const IDURL = `https://raw.githubusercontent.com/MAL-Dubs/MAL-Dubs/main/data/dubIDs.json`;GM_addStyle(GM_getResourceText('CSS'));var dubbedIDs = JSON.parse(localStorage.getItem('dubIDs'));if(dubbedIDs === null){GM_xmlhttpRequest({method: "GET",url: IDURL,onload: function(response) {dubbedIDs = JSON.parse(response.responseText);localStorage.setItem('dubIDs',response.responseText);onComplete();localStorage.setItem('dubCacheDate',Date.now());}});} else {onComplete();dubCache();}function onComplete() {if (document.location.href.match(/.*\/animelist\/.*/)) {setTimeout(()=>parseList(),0);} else {parseSite();if (document.location.href.match(filteruri)) {searchFilter();}if (document.location.href.match(rgx)) {animePages();}setTimeout(()=>labelThumbnails(),400);}}function dubCache() {if (localStorage.getItem('dubCacheDate') === null){localStorage.setItem('dubCacheDate',Date.now());}if(parseInt(localStorage.getItem('dubCacheDate'))+1800000<Date.now()){GM_xmlhttpRequest({method: "GET",url: IDURL,revalidate: true,onload: function(response) {localStorage.setItem('dubIDs',response.responseText);localStorage.setItem('dubCacheDate',Date.now());}});}}function scanList() {let listEntries = document.querySelectorAll('#list-container>div.list-block>div>table>tbody[class=list-item]>tr.list-table-data>td.data.title>a.link,div#list_surround>table>tbody>tr>td>a.animetitle');listEntries.forEach( e => {var id = parseInt(e.href.match(/\/(\d+)\//)[1]);if (e.id === 'checked') {return true;} else {e.id = 'checked';if (dubbedIDs.includes(id)){e.title = "Dubbed";}}});}function parseSite() {labelThumbnails();for (var entry of dubbedLinks.entries()) {if (rgx.test(dubbedLinks.item(entry[0]).getAttribute('href'))) {var linkid = parseInt(rgx.exec(dubbedLinks.item(entry[0]).getAttribute('href'))[2]);if (dubbedIDs.includes(linkid)) {dubbedLinks.item(entry[0]).title = "Dubbed";} else {dubbedLinks.item(entry[0]).title = "Undubbed";}}}}function animePages() {var thispage = rgx.exec(document.location.href)[2];if (dubbedIDs.includes(parseInt(thispage))) {var pagetitle = document.querySelectorAll("h1.title-name")[0];pagetitle.title = "Dubbed";}for (var rec of dubbedRecs.entries()) {var recID = parseInt(recrgx.exec(dubbedRecs.item(rec[0]))[2].replace(thispage+"-", "").replace("-"+thispage,""));if (dubbedIDs.includes(recID)) {dubbedRecs.item(rec[0]).title = "Dubbed";dubbedRecs.item(rec[0]).classList.add("imagelink");}}}function addScrollListener() {document.addEventListener("scroll", function scroll(event) {event.currentTarget.removeEventListener(event.type, scroll);scanList();setTimeout(() => addScrollListener(), 1000);});}function parseList() {setTimeout(function() {scanList();addScrollListener();}, 50);}function labelThumbnails() {document.querySelectorAll(dubbedThumbs).forEach(e => {var thumbID = parseInt(e.href.match(/\/(\d+)\//)[1]);if (dubbedIDs.includes(thumbID)) {e.title = "Dubbed";e.classList.add("imagelink");} else {e.title = "Undubbed";}});}function hideUndubbed(links) {links.forEach(e => {if(document.location.href.match(/.*\/topanime\.php.*/)){e.parentNode.parentNode.parentNode.parentNode.parentNode.classList.add("hidden");} else {e.parentNode.parentNode.classList.add("hidden");}});}function showUndubbed(links) {links.forEach(e => {if(document.location.href.match(/.*\/topanime\.php.*/)){e.parentNode.parentNode.parentNode.parentNode.parentNode.classList.remove("hidden");} else {e.parentNode.parentNode.classList.remove("hidden");}});}function searchFilter() {let undubbed = document.querySelectorAll('[title="Undubbed"]'),filterTarget = document.querySelector('.js-search-filter-block>div.fl-r.di-ib.mt4.mr12,div.horiznav-nav-seasonal>span[data-id="sort"],h2.top-rank-header2>span.fs10.fw-n.ff-Verdana.di-ib.ml16,.normal_header.js-search-filter-block>.di-ib,.normal_header>div.fl-r.di-ib.fs11.fw-n'),filterCheckbox = document.createElement('input'),label = document.createElement('label');if(filterTarget !== null){filterCheckbox.type = 'checkbox';filterCheckbox.id = 'undubbed-filter';label.setAttribute('for','undubbed-filter');label.className = 'fs11 fl-r btn-show-undubbed mr12 fw-n';label.appendChild(document.createTextNode('Dub Only'));filterTarget.after(filterCheckbox);filterCheckbox.after(label);}let filter = true;let filterUndubbed = (localStorage.getItem('dubOnlySearch') === "true");if(filterUndubbed === null){filterUndubbed = false;localStorage.setItem('dubOnlySearch', filterUndubbed);filterCheckbox.checked = filterUndubbed;filter = false;}if (filter) {filterCheckbox.checked = filterUndubbed;if(filterCheckbox.checked === true) {hideUndubbed(undubbed);}}filterCheckbox.addEventListener('change',function () {if(filterCheckbox.checked === true){hideUndubbed(undubbed);}if(filterCheckbox.checked === false){showUndubbed(undubbed);}localStorage.setItem('dubOnlySearch', filterCheckbox.checked);},false);}})();