返回首頁 

Greasy Fork is available in English.

Highlight OCH links

Link Checker. Hit escape to check whether one-click hoster links are online or offline. Press Esc + Shift to remove offline links


Установить этот скрипт?
Рекомендуемый автором скрипт

Вам также может понравится Multi-OCH Helper.


Установить этот скрипт
// ==UserScript==// @name             Highlight OCH links// @namespace        cuzi// @license          MIT// @description      Link Checker. Hit escape to check whether one-click hoster links are online or offline. Press Esc + Shift to remove offline links// @icon             https://raw.githubusercontent.com/cvzi/Userscripts/master/Multi-OCH/icons/och.png// @contributionURL  https://buymeacoff.ee/cuzi// @contributionURL  https://ko-fi.com/cuzicvzi// @compatible       firefox Greasemonkey// @compatible       chrome Tampermonkey. Allow all domains on first run.// @homepageURL      https://openuserjs.org/scripts/cuzi/Highlight_OCH_links// @require          https://greasyfork.org/scripts/370011-requestqueue/code/RequestQueue.js// @require          https://greasyfork.org/scripts/25445-och-list/code/OCH%20List.js// @grant            GM_xmlhttpRequest// @grant            GM.xmlHttpRequest// @grant            GM.registerMenuCommand// @connect          *// @version          24.0// @match            *://*/*// @exclude          *.yahoo.*// @exclude          *.google.*// @exclude          *.youtube.*// @exclude          *.bing.com*// @exclude          *yandex.com*// @exclude          *duckduckgo.com*// ==/UserScript==/* globals RequestQueue, getOCH, NodeFilter, GM, crypto *//* jshint asi: true, esversion: 8 */(function () {'use strict'// Maximal number of links that are checked (per website)const MAXREQUESTS = 2000// Maximal number of links that are checked in parallel (per website)const MAXPARALLELCONNECTIONS = 50// Maximal number of DOM nodes that are examined. Decrease this number on slow machines.const MAXTEXTNODES = 10000// Maximum download size per link (in KB). If you have activated direct downloads, the script will try to download the whole file instead of checking the link. This limit prevents this.const MAXDOWNLOADSIZE = 2000 // kilobytes/*// Exportvar mypatterns = [];var mynames = [];var myurls = [];for(var key in OCH) {var o = OCH[key];if((""+o.check).length > 30) { // If check function implementedmypatterns.push(o.pattern.toString());mynames.push("'"+key+"'");myurls.push(" - ["+o.title+"]("+o.homepage+")");}}alert(mypatterns.join(",\n"));alert(mynames.join(",\n"));alert(myurls.join("\n"));*/let links = [] // [  { hoster: "", url: "", element: DOMNode} , ...   ]let deleteOfflineLinks = falseconst rq = new RequestQueue(MAXPARALLELCONNECTIONS, MAXREQUESTS)// Get OCH listconst OCH = getOCH(rq, MAXDOWNLOADSIZE)function linkOffline (link) {link.element.style.backgroundColor = 'rgba(255, 0, 20, 0.5)'link.element.dataset.linkValidatedAs = 'offline'if (deleteOfflineLinks) {link.element.remove()}}function linkOnline (link) {link.element.style.backgroundColor = 'rgba(70, 255 ,0, 0.5)'link.element.dataset.linkValidatedAs = 'online'highlightInSidebar(link)}function linkWaiting (link) {link.element.classList.add('ochlink713')link.element.style.backgroundColor = 'rgba(255, 150, 80, 0.4)'}function handleR###lt (link, r###lt, errorstring) {if (r###lt === 1) {linkOnline(link)} else if (r###lt === 0) {linkOffline(link)} else if (r###lt === -1) {link.element.style.backgroundColor = 'blue'link.element.title = errorstringconsole.log(errorstring)} else {console.log('handleR###lt(link,r###lt,errorstring) wrong r###ltcode: ' + r###lt)}}let sidebar = nullfunction createSidebar () {sidebar = document.body.appendChild(document.createElement('div'))sidebar.classList.add('och453_sidebar')sidebar.addEventListener('click', function (ev) {if (ev.target === sidebar) {window.scrollTo(0, ev.layerY / sidebar.clientHeight * document.body.clientHeight)} else if ('linkId' in ev.target.dataset) {document.querySelector(`.link_${ev.target.dataset.linkId}`).scrollIntoView()}})document.head.appendChild(document.createElement('style')).innerHTML = `.och453_sidebar {position: fixed;top: 17px;right: 0;bottom:17px;width: 20px;background-color: rgba(255, 255, 255, 0.5);z-index: 1000}.och453_line {position: absolute;height: 3px;width: 100%;background-color:rgba(70, 255 ,0, 0.5);cursor:pointer}`}function cumulativeOffset (element) {// Count scrollable parent elementslet counter = 0let parent = element.parentElementwhile (parent && parent !== document.documentElement) {if (parent.scrollHeight > parent.clientHeight) {counter++}parent = parent.parentElement}// Skip scrollable parent elements except the top-most oneparent = element.parentElementlet i = 0while (parent && parent !== document.documentElement) {if (parent.scrollHeight > parent.clientHeight) {i++if (i === counter) {break}}parent = parent.parentElement}// Calculate offsetlet top = 0while (parent && parent !== document.documentElement) {top += parent.offsetTopparent = parent.offsetParent}return top}function highlightInSidebar (link) {if (!sidebar) {createSidebar()}const top = cumulativeOffset(link.element)const totalHeight = document.body.clientHeightconst topPercentage = top / totalHeight * 100const line = sidebar.appendChild(document.createElement('div'))line.classList.add('och453_line')line.style.top = `${topPercentage}%`const id = crypto.randomUUID()link.element.classList.add(`link_${id}`)line.dataset.linkId = id}function matchHoster (str) {// Return name of first hoster that matches, otherwise return falsefor (const name in OCH) {for (let i = 0; i < OCH[name].pattern.length; i++) {if (OCH[name].pattern[i].test(str)) {return name}}}return false}let stylesheetAdded = falsefunction addStylesheet () {if (stylesheetAdded) {return}document.head.appendChild(document.createElement('style')).innerHTML = `.ochlink713 {transition: background-color 700ms;}`stylesheetAdded = true}function findLinks () {addStylesheet()links = []// Normalize hoster object: Replace single patterns with arrays [RegExp]for (const name in OCH) {if (!Array.isArray(OCH[name].pattern)) {OCH[name].pattern = [OCH[name].pattern]}}// Find all text nodes that contain "http://"const nodes = []const walk = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, {acceptNode: function (node) {if (node.parentNode.href || node.parentNode.parentNode.href || node.parentNode.parentNode.parentNode.href) { return NodeFilter.FILTER_REJECT }if (node.parentNode.tagName === 'TEXTAREA' || node.parentNode.parentNode.tagName === 'TEXTAREA') { return NodeFilter.FILTER_REJECT }if (node.data.match(/(\s|^)https?:\/\/\w+/)) { return NodeFilter.FILTER_ACCEPT }}}, false)let node = walk.nextNode()while (node) {nodes.push(node)node = walk.nextNode()}// For each found text nodes check whether the URL is a valid OCH URLfor (let i = 0; i < nodes.length && i < MAXTEXTNODES; i++) {if (nodes[i].data === '') {continue}const httpPosition = nodes[i].data.indexOf('http')if (httpPosition === -1) {continue}let urlnodeif (httpPosition > 0) {urlnode = nodes[i].splitText(httpPosition) // Split leading text} else {urlnode = nodes[i]}const stop = urlnode.data.match(/$|\s/)[0] // Find end of URLif (stop !== '') { // If empty string, we found $ end of stringconst nextnode = urlnode.splitText(urlnode.data.indexOf(stop)) // Split trailing textif (nextnode.data !== '' && nextnode.data.indexOf('http') !== -1) { // The trailing text might contain another URLnodes.push(nextnode)}}// Check whether the URL is a OCH. If so, create an <a> elementconst url = urlnode.dataconst mh = matchHoster(url)if (mh !== false) {const a = document.createElement('a')a.href = urla.appendChild(urlnode.parentNode.replaceChild(a, urlnode))links.push({hoster: mh,url,element: a})}}// Find actual <a> linksconst deleteNodes = []const al = document.getElementsByTagName('a')for (let i = 0; i < al.length; i++) {if (al[i].dataset.linkValidatedAs) {if (deleteOfflineLinks && al[i].dataset.linkValidatedAs === 'offline') {deleteNodes.push(al[i])}continue // Link was already checked}const mH = matchHoster(al[i].href)if (mH !== false) {links.push({hoster: mH,url: al[i].href,element: al[i]})}}deleteNodes.forEach(e => e.remove())return links.length}function checkLinks () {// Check all links by calling the hoster's check functionfor (let i = 0; i < links.length; i++) {if (links[i] && OCH[links[i].hoster].check && typeof (OCH[links[i].hoster].check) === 'function') {linkWaiting(links[i])OCH[links[i].hoster].check(links[i], handleR###lt)}}}function toggleCheck () {if (!rq.hasRunning()) {// Highlight links and check themrq.resetTotal()const n = findLinks()if (n > 0) {checkLinks()}} else {// Abort all requestsrq.abort()}}document.addEventListener('keydown', function (ev) {if (ev.key === 'Escape') {deleteOfflineLinks = ev.shiftKeytoggleCheck()}}, false)// Manual check from menuGM.registerMenuCommand('Check links', function () {toggleCheck()})// Manual check from menuGM.registerMenuCommand('Remove offline links', function () {deleteOfflineLinks = truetoggleCheck()})})()