全てのサイトでGM_xmlHttpRequestを使うスクリプト

過去にも似たような試みはあったけど、今のバージョンだとunsafeWindowからGM_xmlhttpRequestを呼び出した瞬間アウトで、できませんでした。

でも、どうしても使いたい!という局面に当たってしまったので、試しに作ってみました。インストールすると、全てのサイトでGM_xmlHttpRequestという関数が無条件に使えます。利用する場合は関数名は変えて、こっそり使うのがいいでしょう。

// ==UserScript==
// @name           GM_xmlhttpRequest
// @namespace      GM_xmlhttpRequest
// @include        *
// ==/UserScript==

function run(fn) {
	location.href = "javascript:" + (typeof fn === "function" ? "(" + fn.toString() + ")();" : fn) + "void 0";
}

run(function () {

var count = 0;

var space = window.GM_xmlhttpRequest  = function (req) {
	var key = count++;
	["onload", "onerror", "onreadystatechange"].forEach(function (on) {
		if (typeof req[on] === "function") {
			space[on] = space[on] || {};
			space[on][key] = req[on];
			req[on] = true;
		}
	});
	req.key = key;
	var xhr = document.createElement("input");
	xhr.setAttribute("type", "hidden");
	xhr.setAttribute("value", JSON.stringify(req));
	xhr.setAttribute("class", "GM_xmlhttpRequest");
	document.body.appendChild(xhr);
};

});

function run_GM_xmlhttpRequest(req) {
	var key = req.key;
	["onload", "onerror", "onreadystatechange"].forEach(function (on) {
		if (req[on]) {
			req[on] = function (req) {
				run("GM_xmlhttpRequest.onload['" + key + "'](" + JSON.stringify(req) + ");");
			};
		}
	});
	delete req.key;
	GM_xmlhttpRequest(req);
}

setInterval(function () {
	var xhr = document.getElementsByClassName("GM_xmlhttpRequest");
	if (xhr.length) {
		xhr = xhr[0].parentNode.removeChild(xhr[0]);
		run_GM_xmlhttpRequest(JSON.parse(xhr.getAttribute("value")));
	}
}, 300);

APIとかうまく組み込むことができれば、もしかすると使えるかもしれません。が、今はそれどころじゃないので、とりあえず、これで終わりです。

カスタムイベントだと無理だった。