71 lines
2.1 KiB
JavaScript
71 lines
2.1 KiB
JavaScript
|
// ==UserScript==
|
||
|
// @name Abort Network Requests on Escape
|
||
|
// @namespace blankie-scripts
|
||
|
// @match http*://*/*
|
||
|
// @grant none
|
||
|
// @version 1.0.0
|
||
|
// @author blankie
|
||
|
// @description Aborts network requests invoked from XMLHttpRequest and fetch() when Escape is pressed
|
||
|
// @run-at document-start
|
||
|
// @inject-into page
|
||
|
// ==/UserScript==
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
let activeXHRs = new Set();
|
||
|
let abortControllers = new Set();
|
||
|
|
||
|
|
||
|
unsafeWindow.XMLHttpRequest = new Proxy(unsafeWindow.XMLHttpRequest, {
|
||
|
construct: function(target, args) {
|
||
|
let xhr = new target(...args);
|
||
|
xhr.addEventListener("loadstart", function() {
|
||
|
activeXHRs.add(this);
|
||
|
}, {passive: true});
|
||
|
xhr.addEventListener("loadend", function() {
|
||
|
activeXHRs.delete(this);
|
||
|
}, {passive: true});
|
||
|
return xhr;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
let originalFetch = unsafeWindow.fetch;
|
||
|
unsafeWindow.fetch = function(resource, options = undefined) {
|
||
|
let abortController = new AbortController();
|
||
|
options = options || {};
|
||
|
|
||
|
let originalSignal = options.signal;
|
||
|
if (originalSignal) {
|
||
|
originalSignal.addEventListener("abort", function() {
|
||
|
abortController.abort(originalSignal.reason);
|
||
|
}, {passive: true});
|
||
|
}
|
||
|
options.signal = abortController.signal;
|
||
|
|
||
|
abortControllers.add(abortController);
|
||
|
|
||
|
return originalFetch.call(this, resource, options).finally(function() {
|
||
|
abortControllers.delete(abortController);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
function abortAllRequests() {
|
||
|
for (let activeXHR of activeXHRs) {
|
||
|
activeXHR.abort();
|
||
|
}
|
||
|
activeXHRs.clear();
|
||
|
|
||
|
let error = new DOMException("Network request cancelled by Abort Network Requests on Escape", "NetworkError");
|
||
|
for (let abortController of abortControllers) {
|
||
|
abortController.abort(error);
|
||
|
}
|
||
|
abortControllers.clear();
|
||
|
}
|
||
|
|
||
|
window.addEventListener("keydown", function(event) {
|
||
|
if (event.key !== "Escape" || event.target !== document.body || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
|
||
|
return;
|
||
|
}
|
||
|
abortAllRequests();
|
||
|
}, {passive: true});
|