diff options
Diffstat (limited to 'js/dav/lib/xmlhttprequest.js')
-rw-r--r-- | js/dav/lib/xmlhttprequest.js | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/js/dav/lib/xmlhttprequest.js b/js/dav/lib/xmlhttprequest.js new file mode 100644 index 00000000..d6c1c7cc --- /dev/null +++ b/js/dav/lib/xmlhttprequest.js @@ -0,0 +1,98 @@ +let debug = require('./debug')('dav:xmlhttprequest'); + +let Native; +if (typeof self !== 'undefined' && 'XMLHttpRequest' in self) { + Native = self.XMLHttpRequest; +} else { + // Trick browserify into not loading XMLHttpRequest polyfill + // since it is available in the platform (including web workers) + Native = require(false || 'xmlhttprequest').XMLHttpRequest; +} + +/** + * @fileoverview Promise wrapper around native xhr api. + */ +export default class XMLHttpRequest { + constructor(options) { + this.request = new Native(options); + this.sandbox = null; + + /* readwrite */ + [ + 'response', + 'responseText', + 'responseType', + 'responseXML', + 'timeout', + 'upload', + 'withCredentials' + ].forEach(attribute => { + Object.defineProperty(this, attribute, { + get: function() { return this.request[attribute]; }, + set: function(value) { this.request[attribute] = value; } + }); + }); + + /* readonly */ + [ + 'status', + 'statusText' + ].forEach(attribute => { + Object.defineProperty(this, attribute, { + get: function() { return this.request[attribute]; } + }); + }); + } + + abort() { + return this._callNative('abort', arguments); + } + + getAllResponseHeaders() { + return this._callNative('getAllResponseHeaders', arguments); + } + + getResponseHeader() { + return this._callNative('getResponseHeader', arguments); + } + + open() { + return this._callNative('open', arguments); + } + + overrideMimeType() { + return this._callNative('overrideMimeType', arguments); + } + + setRequestHeader() { + return this._callNative('setRequestHeader', arguments); + } + + send(data) { + debug(`Sending request data: ${data}`); + if (this.sandbox) this.sandbox.add(this); + let request = this.request; + request.send(data); + return new Promise(function(resolve, reject) { + request.onreadystatechange = function() { + if (request.readyState !== 4 /* done */) { + return; + } + + if (request.status < 200 || request.status >= 400) { + return reject(new Error(`Bad status: ${request.status}`)); + } + + return resolve(request.responseText); + }; + + request.ontimeout = function() { + reject(new Error(`Request timed out after ${request.timeout} ms`)); + }; + }); + } + + _callNative(method, args) { + return this.request[method].apply(this.request, args); + } +} |