Greasy Fork is available in English.
Show if manga is licensed in English.
当前为
// ==UserScript==
// @name Licensed (in English)
// @namespace http://tampermonkey.net/
// @version 0.2
// @description Show if manga is licensed in English.
// @author Santeri Hetekivi
// @match https://mangadex.org/title/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=mangadex.org
// @grant GM.xmlHttpRequest
// ==/UserScript==
(function() {
'use strict';
// ID for result element.
const ID_RESULT = "licensedInEnglishResult"
// Colors for different results.
const COLOR_ERROR = "yellow"
const COLOR_LICENSED = "red"
const COLOR_UNLICENSED = "green"
// Milliseconds to sleep multiplied by try counter.
const MS_SLEEP = 1000
// Start for Manga Updates series url.
const URL_START_MANGAUPDATES = "https://www.mangaupdates.com/series.html?id="
// Querys for elements.
// Parent to store result element in.
const QUERY_PARENT = ".title"
// Query for getting link for Manga Updates.
const QUERY_LINK_MANGAUPDATES = "a[href^='"+URL_START_MANGAUPDATES+"']"
// Query for getting elements that can contain TEXT_LICENSED_IN_ENGLISH text.
const QUERY_MANGAUPDATES_LICENSED_IN_ENGLISH = ".sCat b"
// Texts.
const TEXT_LICENSED_IN_ENGLISH = "Licensed (in English)"
const TEXT_LICENSED_POSITIVE = "Yes"
const TEXT_LICENSED_NEGATIVE = "No"
// Update result element.
const updateLicensedInEnglishText = (_elementResult, _text, _color = "yellow") => {
_elementResult.style.color = _color
_elementResult.textContent = _text;
}
// Select node list with given _query.
const selectNodeList = (_query, _document = document) => {
const nodeList = _document.querySelectorAll(_query);
if(!(nodeList instanceof NodeList))
{
throw "nodeList for query '"+_query+"' was not instance of NodeList!"
}
return nodeList
}
// Select single element.
const selectElement = (_query) => {
// Get node list.
const nodeList = selectNodeList(_query);
// Check that got only single result.
const lengthNodeList = nodeList.length
if(lengthNodeList !== 1)
{
throw "Found "+lengthNodeList+" nodes for '"+_query+"'!"
}
// Check that single element is instance of Element.
const element = nodeList[0]
if(!(element instanceof Element))
{
throw "Element for query "+_query+" was not instance of Element!"
}
// Return gotten element.
return element
}
// Get element for result.
const getElementResult = () => {
return document.getElementById(ID_RESULT)
}
// Output given _error to console.
const consoleError = (_error) => {
console.error("Licensed (in English)", _error)
}
// Handle given _error.
const handleError = (_error) => {
// Output to console.
consoleError(_error)
// Get element for result.
const elementResult = getElementResult()
// If element result found.
if(elementResult instanceof Element)
{
// Update error to result element.
updateLicensedInEnglishText(
elementResult,
_error,
COLOR_ERROR
)
}
}
// Check that given _element is instance of Element.
const checkIsElement = (_element, _name) => {
if(!(_element instanceof Element))
{
throw _name+" was not instance of Element!"
}
return _element
}
// Get element with TEXT_LICENSED_IN_ENGLISH text.
const getElementLicensedInEnglish = (_document) => {
// Loop node list.
const nodeList = selectNodeList(QUERY_MANGAUPDATES_LICENSED_IN_ENGLISH, _document)
let element = null
for (let i = 0; i < nodeList.length; i++)
{
// Get element.
element = checkIsElement(nodeList[i], "nodeList["+i+"]")
// If text matches
if (element.textContent == TEXT_LICENSED_IN_ENGLISH)
{
// return element.
return element
}
}
// No element found.
throw "No element with text '"+TEXT_LICENSED_IN_ENGLISH+"' found!"
}
// Get text answer for lisenced in english.
const getTextLisencedInEnglish = (_document) => {
// Get text.
const text = checkIsElement(
checkIsElement(
getElementLicensedInEnglish(_document).parentElement ?? null,
"getElementLicensedInEnglish.parentElement"
).nextElementSibling ?? null,
"getElementLicensedInEnglish.parentElement.nextElementSibling"
).textContent.trim()
// Check gotten text.
if(
text !== TEXT_LICENSED_POSITIVE
&&
text !== TEXT_LICENSED_NEGATIVE
)
{
throw "Invalid text: "+text
}
// Return text.
return text
}
// Handle response.
const handleResponse = (_response) => {
// Get answer for lisenced in english.
const lisencedInEnglish = getTextLisencedInEnglish(
(
new DOMParser()
).parseFromString(
_response.responseText,
'text/html'
)
)
// Update result element.
updateLicensedInEnglishText(
checkIsElement(
getElementResult(),
"getElementResult"
),
lisencedInEnglish,
(
(lisencedInEnglish === TEXT_LICENSED_NEGATIVE) ?
COLOR_UNLICENSED :
(
(lisencedInEnglish === TEXT_LICENSED_POSITIVE) ?
COLOR_LICENSED :
COLOR_ERROR
)
)
)
}
// Get url for Manga Updates.
const getURLMangaUpdates = () => {
// Init urls array
const urls = []
// Loop node list.
const nodeList = selectNodeList(QUERY_LINK_MANGAUPDATES)
for (let i = 0; i < nodeList.length; i++)
{
// Get href
let href = checkIsElement(nodeList[i], "nodeList["+i+"]").href ?? null
// If got href as string
if (typeof href === "string")
{
// Trim href.
href = href.trim()
// If href not already in urls
if(!urls.includes(href))
{
// add href to urls.
urls.push(href)
}
}
}
// Check that has only one url.
const lengthUrls = urls.length
if(lengthUrls !== 1)
{
throw "Found "+lengthUrls+" Manga Updates urls: "+urls.join(",")
}
// Return url.
return urls[0]
}
// Run logic.
const run = (_counter = 0) => {
// Get parent elements.
const parentElementsLength = selectNodeList(QUERY_PARENT).length
// If
if(
// no parent values found
parentElementsLength === 0
&&
// and call counter is under 10.
_counter < 10
)
{
// Increment counter.
_counter++
// Call after timeout.
setTimeout(
() => {
try
{
run(_counter)
}
catch(_error)
{
handleError(_error)
}
},
MS_SLEEP*_counter
);
// Return.
return
}
// Throw error if found other than 0 or 1 elements.
else if(parentElementsLength !== 1)
{
throw "Found "+parentElementsLength+" nodes for '"+QUERY_PARENT+"'!"
}
// Get result element.
let elementResult = getElementResult(ID_RESULT)
// If no result element found.
if(!(elementResult instanceof Element))
{
// Create result element.
elementResult = document.createElement("p")
elementResult.id = ID_RESULT
selectElement(QUERY_PARENT).appendChild(elementResult);
}
// Update result to unknown.
updateLicensedInEnglishText(
elementResult,
"Unknown",
COLOR_ERROR
)
// Get Manga Updates page.
GM.xmlHttpRequest(
{
method: "GET",
url: getURLMangaUpdates(),
headers: {
"Accept": "text/html"
},
onload: function(_response) {
// Handle response.
try
{
handleResponse(_response)
}
catch(_error)
{
handleError(_error)
}
},
onerror: (_response) => {
consoleError(_response)
handleError(_response.error ?? "Unknown error!")
},
ontimeout: (_response) => {
consoleError(_response)
handleError(_response.error ?? "Unknown timeout!")
},
onabort: (_response) => {
consoleError(_response)
handleError(_response.error ?? "Unknown timeout!")
}
}
);
}
// Try to start running.
try
{
// Make sure that document is instance of HTMLDocument.
if(!(document instanceof HTMLDocument))
{
throw "document was not instance of HTMLDocument!"
}
run()
}
catch(_error)
{
handleError(_error)
}
})();