返回首頁 

GM web hooks

Makes GM_xmlhttpRequest and GM_download queued

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greasyfork.org/scripts/460385/1221394/GM%20web%20hooks.js

/* eslint-disable no-multi-spaces *//* eslint-disable no-native-reassign *//* eslint-disable no-redeclare */// ==UserScript==// @name               GM web hooks// @namespace          GM-web-hooks// @version            0.1.2// @description        Makes GM_xmlhttpRequest and GM_download queued// @author             PY-DNG// @license            GPL-v3// ==/UserScript==/* global LogLevel DoLog Err $ $All $CrE $AEL addStyle destroyEvent copyProp copyProps parseArgs escJsStr replaceText getUrlArgv dl_browser dl_GM AsyncManager *//* global GM_xmlhttpRequest GM_download */let [GMXHRHook, GMDLHook] = (function __MAIN__() {'use strict';return [GMXHRHook, GMDLHook];// GM_XHR HOOK: The number of running GM_XHRs in a time must under maxXHR// Returns the abort function to stop the request anyway(no matter it's still waiting, or requesting)// (If the request is invalid, such as url === '', will return false and will NOT make this request)// If the abort function called on a request that is not running(still waiting or finished), there will be NO onabort event// Requires: function delItem(){...} & function uniqueIDMaker(){...}function GMXHRHook(maxXHR=5) {const GM_XHR = GM_xmlhttpRequest;const getID = function() {let id = 0;return () => id++;}();let todoList = [], ongoingList = [];GM_xmlhttpRequest = safeGMxhr;function safeGMxhr() {// Get an id for this request, arrange a request object for it.const id = getID();const request = {id: id, args: arguments, aborter: null};// Deal onload function firstdealEndingEvents(request);/* DO NOT DO THIS! KEEP ITS ORIGINAL PROPERTIES!// Stop invalid requestsif (!validCheck(request)) {return false;}*/// Judge if we could start the request now or later?todoList.push(request);checkXHR();return makeAbortFunc(id);// Decrease activeXHRCount while GM_XHR onload;function dealEndingEvents(request) {const e = request.args[0];// onload eventconst oriOnload = e.onload;e.onload = function() {reqFinish(request.id);checkXHR();oriOnload ? oriOnload.apply(null, arguments) : function() {};}// onerror eventconst oriOnerror = e.onerror;e.onerror = function() {reqFinish(request.id);checkXHR();oriOnerror ? oriOnerror.apply(null, arguments) : function() {};}// ontimeout eventconst oriOntimeout = e.ontimeout;e.ontimeout = function() {reqFinish(request.id);checkXHR();oriOntimeout ? oriOntimeout.apply(null, arguments) : function() {};}// onabort eventconst oriOnabort = e.onabort;e.onabort = function() {reqFinish(request.id);checkXHR();oriOnabort ? oriOnabort.apply(null, arguments) : function() {};}}// Check if the request is invalidfunction validCheck(request) {const e = request.args[0];if (!e.url) {return false;}return true;}// Call a XHR from todoList and push the request object to ongoingList if calledfunction checkXHR() {if (ongoingList.length >= maxXHR) {return false;};if (todoList.length === 0) {return false;};const req = todoList.shift();const reqArgs = req.args;const aborter = GM_XHR.apply(null, reqArgs);req.aborter = aborter;ongoingList.push(req);return req;}// Make a function that aborts a certain requestfunction makeAbortFunc(id) {return function() {let i;// Check if the request haven't been calledfor (i = 0; i < todoList.length; i++) {const req = todoList[i];if (req.id === id) {// found this request: haven't been calledtodoList.splice(i, 1);return true;}}// Check if the request is running nowfor (i = 0; i < ongoingList.length; i++) {const req = todoList[i];if (req.id === id) {// found this request: running nowreq.aborter();reqFinish(id);checkXHR();}}// Oh no, this request is already finished...return false;}}// Remove a certain request from ongoingListfunction reqFinish(id) {let i;for (i = 0; i < ongoingList.length; i++) {const req = ongoingList[i];if (req.id === id) {ongoingList = ongoingList.splice(i, 1);return true;}}return false;}}}// GM_DL HOOK: The number of running GM_download in a time must under maxDL// Returns the abort function to stop the request anyway(no matter it's still waiting, or requesting)// (If the request is invalid, such as url === '', will return false and will NOT make this request)// If the abort function called on a request that is not running(still waiting or finished), there will be NO onabort event// Requires: function delItem(){...} & function uniqueIDMaker(){...}function GMDLHook(maxDL=5) {const GM_DL = GM_download;const getID = function() {let id = 0;return () => id++;}();let todoList = [], ongoingList = [];GM_download = safeGMdl;function safeGMdl() {// Get an id for this request, arrange a request object for it.const id = getID();const request = {id: id, args: arguments, aborter: null};// Deal onload function firstdealEndingEvents(request);/* DO NOT DO THIS! KEEP ITS ORIGINAL PROPERTIES!// Stop invalid requestsif (!validCheck(request)) {return false;}*/// Judge if we could start the request now or later?todoList.push(request);checkDL();return makeAbortFunc(id);// Decrease activeXHRCount while GM_DL onload;function dealEndingEvents(request) {const e = request.args[0];// onload eventconst oriOnload = e.onload;e.onload = function() {reqFinish(request.id);checkDL();oriOnload ? oriOnload.apply(null, arguments) : function() {};}// onerror eventconst oriOnerror = e.onerror;e.onerror = function() {reqFinish(request.id);checkDL();oriOnerror ? oriOnerror.apply(null, arguments) : function() {};}// ontimeout eventconst oriOntimeout = e.ontimeout;e.ontimeout = function() {reqFinish(request.id);checkDL();oriOntimeout ? oriOntimeout.apply(null, arguments) : function() {};}// onabort eventconst oriOnabort = e.onabort;e.onabort = function() {reqFinish(request.id);checkDL();oriOnabort ? oriOnabort.apply(null, arguments) : function() {};}}// Check if the request is invalidfunction validCheck(request) {const e = request.args[0];if (!e.url) {return false;}return true;}// Call a XHR from todoList and push the request object to ongoingList if calledfunction checkDL() {if (ongoingList.length >= maxDL) {return false;};if (todoList.length === 0) {return false;};const req = todoList.shift();const reqArgs = req.args;const aborter = GM_DL.apply(null, reqArgs);req.aborter = aborter;ongoingList.push(req);return req;}// Make a function that aborts a certain requestfunction makeAbortFunc(id) {return function() {let i;// Check if the request haven't been calledfor (i = 0; i < todoList.length; i++) {const req = todoList[i];if (req.id === id) {// found this request: haven't been calledtodoList.splice(i, 1);return true;}}// Check if the request is running nowfor (i = 0; i < ongoingList.length; i++) {const req = todoList[i];if (req.id === id) {// found this request: running nowreq.aborter();reqFinish(id);checkDL();}}// Oh no, this request is already finished...return false;}}// Remove a certain request from ongoingListfunction reqFinish(id) {let i;for (i = 0; i < ongoingList.length; i++) {const req = ongoingList[i];if (req.id === id) {ongoingList = ongoingList.splice(i, 1);return true;}}return false;}}}})();