summaryrefslogtreecommitdiffstats
path: root/js/vendor/dav/lib/xmlhttprequest.js
blob: d6c1c7cc815a124f52ca6efed9b15f76862309f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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);
  }
}