Skip to content

Instantly share code, notes, and snippets.

@line0
Forked from Acorn-zz/GM_XHR.js
Last active November 30, 2015 15:44
Show Gist options
  • Save line0/dc7cffca7a10ffd1433a to your computer and use it in GitHub Desktop.
Save line0/dc7cffca7a10ffd1433a to your computer and use it in GitHub Desktop.
allows using all Jquery AJAX methods in Greasemonkey
// allows using all Jquery AJAX methods in Greasemonkey
// originally inspired from http://ryangreenberg.com/archives/2010/03/greasemonkey_jquery.php
// works with jQuery 2.1.4
// (c) 2011 Martin Monperrus
// (c) 2010 Ryan Greenberg
// (updated) 2015 line0 to work with current jQuery and more closely mirror contemporary XHR implementations.
//
// Usage:
// $.ajax({
// url: '/p/',
// xhr: function(){return new GM_XHR();},
// type: 'POST',
// success: function(val){
// ....
// }
// });
(function(window) {
'use strict';
var GM_XHR = function() {
GM_XHR.UNSENT = 0;
GM_XHR.OPENED = 1;
GM_XHR.HEADERS_RECEIVED = 2;
GM_XHR.LOADING = 3;
GM_XHR.DONE = 4;
if (!new.target)
return GM_XHR;
var xhrRequestDetails = {headers: {}}
var abortCb = null;
var events = { onloadstart: null, onprogress: null, onabort: null, onerror: null, onload: null, ontimeout: null, onloadend: null };
// XHR attributes
this.status = 0;
this.statusText = '';
this.readyState = GM_XHR.UNSENT;
this.timeout = 0;
this.withCredentials = false;
this.responseURL = '';
this.responseType = '';
this.response = '';
this.upload = Object.assign({}, events);
this.onreadystatechange = null;
// Event attributes
Object.assign(this, events);
// Additional GM_XHR attributes
this.responseHeaders = '';
// XHR methods
this.abort = function() {
if (this.readyState == GM_XHR.UNSENT || this.readyState == GM_XHR.DONE) {
this.readyState = GM_XHR.UNSENT;
} else abortCb();
};
this.getAllResponseHeaders = function(name) {
return this.responseHeaders;
};
this.getResponseHeader = function(name) {
console.log(this.responseHeaders)
var regexp = new RegExp('^'+name+': (.*)$','im');
var match = regexp.exec(this.responseHeaders);
if (match) { return match[1]; }
return null;
};
this.overrideMimeType = function(mime) {
if(this.readyState == GM_XHR.LOADING || this.readyState == GM_XHR.DONE)
throw new Error("Can't override mime type, request already loading or done.");
xhrRequestDetails.overrideMimeType = mime;
};
this.open = function(method, url, _async = true, user = null, password = null) {
if (!_async)
throw new Error("Synchronous XHR is no longer supported.");
Object.assign(xhrRequestDetails, {method: method, url: url, user: user, password: password});
this.readyState = GM_XHR.OPENED;
};
this.setRequestHeader = function(name, value) {
xhrRequestDetails.headers[name] = value;
};
var handleGMXHREvent = (details, handler) => {
Object.assign(this, details);
if (handler)
handler();
}
this.send = data => {
let xhr = this;
abortCb = GM_xmlhttpRequest(Object.assign(xhrRequestDetails, {
data: data,
withCredentials: xhr.withCredentials,
onreadystatechange: details => {
handleGMXHREvent(details, xhr.onreadystatechange);
if (false) console.log(`XHR State change:
state: ${details.readyState}
status: ${details.statusText} (${details.status})
response: ${details.responseText}
`);
},
onabort: d => handleGMXHREvent(d, xhr.onabort),
onerror: d => handleGMXHREvent(d, xhr.onerror),
onload: d => handleGMXHREvent(d, xhr.onload),
onprogress: d => handleGMXHREvent(d, xhr.onprogress),
ontimeout: d => handleGMXHREvent(d, xhr.ontimeout)
})).abort;
};
};
window.GM_XHR = GM_XHR();
})(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment