您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
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) } })();