2015-03-24 21:40:11 +00:00
|
|
|
/**
|
2015-06-05 22:23:30 +00:00
|
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
2015-03-24 21:40:11 +00:00
|
|
|
*
|
2016-05-25 11:17:35 +00:00
|
|
|
* @providesModule XMLHttpRequest
|
2015-06-05 22:23:30 +00:00
|
|
|
* @flow
|
2015-03-24 21:40:11 +00:00
|
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
|
2016-05-25 11:17:35 +00:00
|
|
|
const RCTNetworking = require('RCTNetworking');
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
|
|
|
|
const EventTarget = require('event-target-shim');
|
2016-04-11 12:53:41 +00:00
|
|
|
const invariant = require('fbjs/lib/invariant');
|
|
|
|
const utf8 = require('utf8');
|
|
|
|
const warning = require('fbjs/lib/warning');
|
|
|
|
|
|
|
|
type ResponseType = '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text';
|
|
|
|
type Response = ?Object | string;
|
2015-11-17 14:28:44 +00:00
|
|
|
|
2016-02-17 07:58:49 +00:00
|
|
|
const UNSENT = 0;
|
|
|
|
const OPENED = 1;
|
|
|
|
const HEADERS_RECEIVED = 2;
|
|
|
|
const LOADING = 3;
|
|
|
|
const DONE = 4;
|
|
|
|
|
2016-04-11 12:53:41 +00:00
|
|
|
const SUPPORTED_RESPONSE_TYPES = {
|
|
|
|
arraybuffer: typeof global.ArrayBuffer === 'function',
|
|
|
|
blob: typeof global.Blob === 'function',
|
|
|
|
document: false,
|
|
|
|
json: true,
|
|
|
|
text: true,
|
|
|
|
'': true,
|
|
|
|
};
|
|
|
|
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
const REQUEST_EVENTS = [
|
|
|
|
'abort',
|
|
|
|
'error',
|
|
|
|
'load',
|
|
|
|
'loadstart',
|
|
|
|
'progress',
|
|
|
|
'timeout',
|
|
|
|
'loadend',
|
|
|
|
];
|
|
|
|
|
|
|
|
const XHR_EVENTS = REQUEST_EVENTS.concat('readystatechange');
|
|
|
|
|
|
|
|
class XMLHttpRequestEventTarget extends EventTarget(...REQUEST_EVENTS) {
|
|
|
|
onload: ?Function;
|
|
|
|
onloadstart: ?Function;
|
|
|
|
onprogress: ?Function;
|
|
|
|
ontimeout: ?Function;
|
|
|
|
onerror: ?Function;
|
|
|
|
onloadend: ?Function;
|
|
|
|
}
|
|
|
|
|
2015-03-24 21:40:11 +00:00
|
|
|
/**
|
|
|
|
* Shared base for platform-specific XMLHttpRequest implementations.
|
|
|
|
*/
|
2016-05-25 11:17:35 +00:00
|
|
|
class XMLHttpRequest extends EventTarget(...XHR_EVENTS) {
|
2015-03-24 21:40:11 +00:00
|
|
|
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
static UNSENT: number = UNSENT;
|
|
|
|
static OPENED: number = OPENED;
|
|
|
|
static HEADERS_RECEIVED: number = HEADERS_RECEIVED;
|
|
|
|
static LOADING: number = LOADING;
|
|
|
|
static DONE: number = DONE;
|
2016-02-17 07:58:49 +00:00
|
|
|
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
UNSENT: number = UNSENT;
|
|
|
|
OPENED: number = OPENED;
|
|
|
|
HEADERS_RECEIVED: number = HEADERS_RECEIVED;
|
|
|
|
LOADING: number = LOADING;
|
|
|
|
DONE: number = DONE;
|
2015-03-24 21:40:11 +00:00
|
|
|
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
// EventTarget automatically initializes these to `null`.
|
2015-03-24 21:40:11 +00:00
|
|
|
onload: ?Function;
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
onloadstart: ?Function;
|
|
|
|
onprogress: ?Function;
|
2016-04-15 12:16:53 +00:00
|
|
|
ontimeout: ?Function;
|
|
|
|
onerror: ?Function;
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
onloadend: ?Function;
|
|
|
|
onreadystatechange: ?Function;
|
2015-03-24 21:40:11 +00:00
|
|
|
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
readyState: number = UNSENT;
|
|
|
|
responseHeaders: ?Object;
|
|
|
|
status: number = 0;
|
|
|
|
timeout: number = 0;
|
|
|
|
responseURL: ?string;
|
|
|
|
|
|
|
|
upload: XMLHttpRequestEventTarget = new XMLHttpRequestEventTarget();
|
2015-11-17 14:28:44 +00:00
|
|
|
|
|
|
|
_requestId: ?number;
|
|
|
|
_subscriptions: [any];
|
|
|
|
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
_aborted: boolean = false;
|
2016-04-11 12:53:41 +00:00
|
|
|
_cachedResponse: Response;
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
_hasError: boolean = false;
|
2016-04-11 12:53:41 +00:00
|
|
|
_headers: Object;
|
2015-06-05 22:23:30 +00:00
|
|
|
_lowerCaseResponseHeaders: Object;
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
_method: ?string = null;
|
2016-04-11 12:53:41 +00:00
|
|
|
_response: string | ?Object;
|
|
|
|
_responseType: ResponseType;
|
2016-06-03 01:07:36 +00:00
|
|
|
_responseText: string = '';
|
2016-04-11 12:53:41 +00:00
|
|
|
_sent: boolean;
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
_url: ?string = null;
|
|
|
|
_timedOut: boolean = false;
|
|
|
|
_incrementalEvents: boolean = false;
|
2015-03-24 21:40:11 +00:00
|
|
|
|
|
|
|
constructor() {
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
super();
|
2015-06-05 22:23:30 +00:00
|
|
|
this._reset();
|
|
|
|
}
|
|
|
|
|
2016-04-11 12:53:41 +00:00
|
|
|
_reset(): void {
|
2015-03-24 21:40:11 +00:00
|
|
|
this.readyState = this.UNSENT;
|
|
|
|
this.responseHeaders = undefined;
|
2015-05-22 23:21:58 +00:00
|
|
|
this.status = 0;
|
2016-01-07 18:25:56 +00:00
|
|
|
delete this.responseURL;
|
2015-03-24 21:40:11 +00:00
|
|
|
|
2015-11-17 14:28:44 +00:00
|
|
|
this._requestId = null;
|
|
|
|
|
2016-04-11 12:53:41 +00:00
|
|
|
this._cachedResponse = undefined;
|
|
|
|
this._hasError = false;
|
2015-03-24 21:40:11 +00:00
|
|
|
this._headers = {};
|
2016-06-03 01:07:36 +00:00
|
|
|
this._responseText = '';
|
2016-04-11 12:53:41 +00:00
|
|
|
this._responseType = '';
|
2015-03-24 21:40:11 +00:00
|
|
|
this._sent = false;
|
2015-06-05 22:23:30 +00:00
|
|
|
this._lowerCaseResponseHeaders = {};
|
2015-11-17 14:28:44 +00:00
|
|
|
|
|
|
|
this._clearSubscriptions();
|
2016-04-15 12:16:53 +00:00
|
|
|
this._timedOut = false;
|
2015-11-17 14:28:44 +00:00
|
|
|
}
|
|
|
|
|
2016-04-11 12:53:41 +00:00
|
|
|
// $FlowIssue #10784535
|
|
|
|
get responseType(): ResponseType {
|
|
|
|
return this._responseType;
|
|
|
|
}
|
|
|
|
|
|
|
|
// $FlowIssue #10784535
|
|
|
|
set responseType(responseType: ResponseType): void {
|
|
|
|
if (this.readyState > HEADERS_RECEIVED) {
|
|
|
|
throw new Error(
|
|
|
|
"Failed to set the 'responseType' property on 'XMLHttpRequest': The " +
|
|
|
|
"response type cannot be set if the object's state is LOADING or DONE"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (!SUPPORTED_RESPONSE_TYPES.hasOwnProperty(responseType)) {
|
|
|
|
warning(
|
2016-06-03 01:07:36 +00:00
|
|
|
false,
|
|
|
|
`The provided value '${responseType}' is not a valid 'responseType'.`
|
|
|
|
);
|
2016-04-11 12:53:41 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// redboxes early, e.g. for 'arraybuffer' on ios 7
|
|
|
|
invariant(
|
|
|
|
SUPPORTED_RESPONSE_TYPES[responseType] || responseType === 'document',
|
|
|
|
`The provided value '${responseType}' is unsupported in this environment.`
|
|
|
|
);
|
|
|
|
this._responseType = responseType;
|
|
|
|
}
|
|
|
|
|
2016-06-03 01:07:36 +00:00
|
|
|
// $FlowIssue #10784535
|
|
|
|
get responseText(): string {
|
|
|
|
if (this._responseType !== '' && this._responseType !== 'text') {
|
|
|
|
throw new Error(
|
|
|
|
`The 'responseText' property is only available if 'responseType' ` +
|
|
|
|
`is set to '' or 'text', but it is '${this._responseType}'.`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (this.readyState < LOADING) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
return this._responseText;
|
|
|
|
}
|
|
|
|
|
2016-04-11 12:53:41 +00:00
|
|
|
// $FlowIssue #10784535
|
|
|
|
get response(): Response {
|
|
|
|
const {responseType} = this;
|
|
|
|
if (responseType === '' || responseType === 'text') {
|
|
|
|
return this.readyState < LOADING || this._hasError
|
|
|
|
? ''
|
2016-06-03 01:07:36 +00:00
|
|
|
: this._responseText;
|
2016-04-11 12:53:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.readyState !== DONE) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._cachedResponse !== undefined) {
|
|
|
|
return this._cachedResponse;
|
|
|
|
}
|
|
|
|
|
2016-06-03 01:07:36 +00:00
|
|
|
switch (this._responseType) {
|
2016-04-11 12:53:41 +00:00
|
|
|
case 'document':
|
|
|
|
this._cachedResponse = null;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'arraybuffer':
|
|
|
|
this._cachedResponse = toArrayBuffer(
|
2016-06-03 01:07:36 +00:00
|
|
|
this._responseText, this.getResponseHeader('content-type') || '');
|
2016-04-11 12:53:41 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'blob':
|
|
|
|
this._cachedResponse = new global.Blob(
|
2016-06-03 01:07:36 +00:00
|
|
|
[this._responseText],
|
2016-04-11 12:53:41 +00:00
|
|
|
{type: this.getResponseHeader('content-type') || ''}
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'json':
|
|
|
|
try {
|
2016-06-03 01:07:36 +00:00
|
|
|
this._cachedResponse = JSON.parse(this._responseText);
|
2016-04-11 12:53:41 +00:00
|
|
|
} catch (_) {
|
|
|
|
this._cachedResponse = null;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
this._cachedResponse = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this._cachedResponse;
|
|
|
|
}
|
|
|
|
|
2016-05-25 11:17:35 +00:00
|
|
|
// exposed for testing
|
|
|
|
__didCreateRequest(requestId: number): void {
|
2015-11-17 14:28:44 +00:00
|
|
|
this._requestId = requestId;
|
|
|
|
}
|
|
|
|
|
2016-05-09 17:35:19 +00:00
|
|
|
// exposed for testing
|
|
|
|
__didUploadProgress(requestId: number, progress: number, total: number): void {
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
if (requestId === this._requestId) {
|
|
|
|
this.upload.dispatchEvent({
|
|
|
|
type: 'progress',
|
2015-11-17 14:28:44 +00:00
|
|
|
lengthComputable: true,
|
|
|
|
loaded: progress,
|
|
|
|
total,
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
});
|
2015-11-17 14:28:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-03 01:07:36 +00:00
|
|
|
__didReceiveResponse(
|
|
|
|
requestId: number,
|
|
|
|
status: number,
|
|
|
|
responseHeaders: ?Object,
|
|
|
|
responseURL: ?string
|
|
|
|
): void {
|
2015-11-17 14:28:44 +00:00
|
|
|
if (requestId === this._requestId) {
|
|
|
|
this.status = status;
|
|
|
|
this.setResponseHeaders(responseHeaders);
|
|
|
|
this.setReadyState(this.HEADERS_RECEIVED);
|
2016-01-07 18:25:56 +00:00
|
|
|
if (responseURL || responseURL === '') {
|
|
|
|
this.responseURL = responseURL;
|
|
|
|
} else {
|
|
|
|
delete this.responseURL;
|
|
|
|
}
|
2015-11-17 14:28:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-03 01:07:36 +00:00
|
|
|
__didReceiveData(requestId: number, responseText: string): void {
|
2015-11-17 14:28:44 +00:00
|
|
|
if (requestId === this._requestId) {
|
2016-06-03 01:07:36 +00:00
|
|
|
if (!this._responseText) {
|
|
|
|
this._responseText = responseText;
|
2015-11-17 14:28:44 +00:00
|
|
|
} else {
|
2016-06-03 01:07:36 +00:00
|
|
|
this._responseText += responseText;
|
2015-11-17 14:28:44 +00:00
|
|
|
}
|
2016-04-11 12:53:41 +00:00
|
|
|
this._cachedResponse = undefined; // force lazy recomputation
|
2015-11-17 14:28:44 +00:00
|
|
|
this.setReadyState(this.LOADING);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-09 17:35:19 +00:00
|
|
|
// exposed for testing
|
2016-06-03 01:07:36 +00:00
|
|
|
__didCompleteResponse(
|
|
|
|
requestId: number,
|
|
|
|
error: string,
|
|
|
|
timeOutError: boolean
|
|
|
|
): void {
|
2015-11-17 14:28:44 +00:00
|
|
|
if (requestId === this._requestId) {
|
|
|
|
if (error) {
|
2016-06-03 01:07:36 +00:00
|
|
|
this._responseText = error;
|
2016-04-11 12:53:41 +00:00
|
|
|
this._hasError = true;
|
2016-04-15 12:16:53 +00:00
|
|
|
if (timeOutError) {
|
|
|
|
this._timedOut = true;
|
|
|
|
}
|
2015-11-17 14:28:44 +00:00
|
|
|
}
|
|
|
|
this._clearSubscriptions();
|
|
|
|
this._requestId = null;
|
|
|
|
this.setReadyState(this.DONE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_clearSubscriptions(): void {
|
|
|
|
(this._subscriptions || []).forEach(sub => {
|
|
|
|
sub.remove();
|
|
|
|
});
|
|
|
|
this._subscriptions = [];
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
getAllResponseHeaders(): ?string {
|
2015-06-05 22:23:30 +00:00
|
|
|
if (!this.responseHeaders) {
|
|
|
|
// according to the spec, return null if no response has been received
|
|
|
|
return null;
|
2015-04-21 23:43:07 +00:00
|
|
|
}
|
2015-06-05 22:23:30 +00:00
|
|
|
var headers = this.responseHeaders || {};
|
|
|
|
return Object.keys(headers).map((headerName) => {
|
|
|
|
return headerName + ': ' + headers[headerName];
|
|
|
|
}).join('\n');
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
getResponseHeader(header: string): ?string {
|
2015-06-05 22:23:30 +00:00
|
|
|
var value = this._lowerCaseResponseHeaders[header.toLowerCase()];
|
|
|
|
return value !== undefined ? value : null;
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
setRequestHeader(header: string, value: any): void {
|
2015-06-05 22:23:30 +00:00
|
|
|
if (this.readyState !== this.OPENED) {
|
|
|
|
throw new Error('Request has not been opened');
|
|
|
|
}
|
2015-05-26 15:12:59 +00:00
|
|
|
this._headers[header.toLowerCase()] = value;
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
open(method: string, url: string, async: ?boolean): void {
|
2015-06-05 22:23:30 +00:00
|
|
|
/* Other optional arguments are not supported yet */
|
2015-03-24 21:40:11 +00:00
|
|
|
if (this.readyState !== this.UNSENT) {
|
|
|
|
throw new Error('Cannot open, already sending');
|
|
|
|
}
|
|
|
|
if (async !== undefined && !async) {
|
|
|
|
// async is default
|
|
|
|
throw new Error('Synchronous http requests are not supported');
|
|
|
|
}
|
2016-01-07 12:00:15 +00:00
|
|
|
if (!url) {
|
|
|
|
throw new Error('Cannot load an empty url');
|
|
|
|
}
|
2015-06-05 22:23:30 +00:00
|
|
|
this._reset();
|
2016-04-13 13:47:29 +00:00
|
|
|
this._method = method.toUpperCase();
|
2015-03-24 21:40:11 +00:00
|
|
|
this._url = url;
|
|
|
|
this._aborted = false;
|
2015-06-05 22:23:30 +00:00
|
|
|
this.setReadyState(this.OPENED);
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
|
|
|
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
sendImpl(
|
|
|
|
method: ?string,
|
|
|
|
url: ?string,
|
|
|
|
headers: Object,
|
|
|
|
data: any,
|
2016-05-25 11:17:35 +00:00
|
|
|
useIncrementalUpdates: boolean,
|
|
|
|
timeout: number,
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
): void {
|
2016-06-01 13:18:17 +00:00
|
|
|
this._subscriptions.push(RCTNetworking.addListener(
|
|
|
|
'didSendNetworkData',
|
|
|
|
(args) => this.__didUploadProgress(...args)
|
|
|
|
));
|
|
|
|
this._subscriptions.push(RCTNetworking.addListener(
|
|
|
|
'didReceiveNetworkResponse',
|
2016-06-03 01:07:36 +00:00
|
|
|
(args) => this.__didReceiveResponse(...args)
|
2016-06-01 13:18:17 +00:00
|
|
|
));
|
|
|
|
this._subscriptions.push(RCTNetworking.addListener(
|
|
|
|
'didReceiveNetworkData',
|
2016-06-03 01:07:36 +00:00
|
|
|
(args) => this.__didReceiveData(...args)
|
2016-06-01 13:18:17 +00:00
|
|
|
));
|
|
|
|
this._subscriptions.push(RCTNetworking.addListener(
|
|
|
|
'didCompleteNetworkResponse',
|
|
|
|
(args) => this.__didCompleteResponse(...args)
|
|
|
|
));
|
2016-05-25 11:17:35 +00:00
|
|
|
RCTNetworking.sendRequest(
|
|
|
|
method,
|
|
|
|
url,
|
|
|
|
headers,
|
|
|
|
data,
|
|
|
|
useIncrementalUpdates,
|
|
|
|
timeout,
|
|
|
|
this.__didCreateRequest.bind(this),
|
|
|
|
);
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
send(data: any): void {
|
|
|
|
if (this.readyState !== this.OPENED) {
|
|
|
|
throw new Error('Request has not been opened');
|
|
|
|
}
|
|
|
|
if (this._sent) {
|
|
|
|
throw new Error('Request has already been sent');
|
|
|
|
}
|
|
|
|
this._sent = true;
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
const incrementalEvents = this._incrementalEvents || !!this.onreadystatechange;
|
|
|
|
this.sendImpl(
|
|
|
|
this._method,
|
|
|
|
this._url,
|
|
|
|
this._headers,
|
|
|
|
data,
|
|
|
|
incrementalEvents,
|
|
|
|
this.timeout
|
|
|
|
);
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
abort(): void {
|
2015-06-05 22:23:30 +00:00
|
|
|
this._aborted = true;
|
2015-11-17 14:28:44 +00:00
|
|
|
if (this._requestId) {
|
|
|
|
RCTNetworking.abortRequest(this._requestId);
|
|
|
|
}
|
2015-03-24 21:40:11 +00:00
|
|
|
// only call onreadystatechange if there is something to abort,
|
|
|
|
// below logic is per spec
|
|
|
|
if (!(this.readyState === this.UNSENT ||
|
|
|
|
(this.readyState === this.OPENED && !this._sent) ||
|
|
|
|
this.readyState === this.DONE)) {
|
2015-06-05 22:23:30 +00:00
|
|
|
this._reset();
|
|
|
|
this.setReadyState(this.DONE);
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
2015-06-05 22:23:30 +00:00
|
|
|
// Reset again after, in case modified in handler
|
|
|
|
this._reset();
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
|
|
|
|
2015-06-05 22:23:30 +00:00
|
|
|
setResponseHeaders(responseHeaders: ?Object): void {
|
|
|
|
this.responseHeaders = responseHeaders || null;
|
|
|
|
var headers = responseHeaders || {};
|
|
|
|
this._lowerCaseResponseHeaders =
|
|
|
|
Object.keys(headers).reduce((lcaseHeaders, headerName) => {
|
|
|
|
lcaseHeaders[headerName.toLowerCase()] = headers[headerName];
|
2015-07-07 21:57:05 +00:00
|
|
|
return lcaseHeaders;
|
2015-06-05 22:23:30 +00:00
|
|
|
}, {});
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
|
|
|
|
2015-06-05 22:23:30 +00:00
|
|
|
setReadyState(newState: number): void {
|
2015-03-24 21:40:11 +00:00
|
|
|
this.readyState = newState;
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
this.dispatchEvent({type: 'readystatechange'});
|
2015-06-05 22:23:30 +00:00
|
|
|
if (newState === this.DONE && !this._aborted) {
|
2016-04-15 12:16:53 +00:00
|
|
|
if (this._hasError) {
|
|
|
|
if (this._timedOut) {
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
this.dispatchEvent({type: 'timeout'});
|
2016-04-15 12:16:53 +00:00
|
|
|
} else {
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
this.dispatchEvent({type: 'error'});
|
2016-04-15 12:16:53 +00:00
|
|
|
}
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
} else {
|
|
|
|
this.dispatchEvent({type: 'load'});
|
2016-04-15 12:16:53 +00:00
|
|
|
}
|
2015-06-05 22:23:30 +00:00
|
|
|
}
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
|
|
|
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
/* global EventListener */
|
|
|
|
addEventListener(type: string, listener: EventListener): void {
|
|
|
|
// If we dont' have a 'readystatechange' event handler, we don't
|
|
|
|
// have to send repeated LOADING events with incremental updates
|
|
|
|
// to responseText, which will avoid a bunch of native -> JS
|
|
|
|
// bridge traffic.
|
|
|
|
if (type === 'readystatechange') {
|
|
|
|
this._incrementalEvents = true;
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
Make XMLHttpRequest and XMLHttpRequest.upload proper EventTargets
Summary:
So far, XHR only supports a few `onfoo` event handlers, not the entier `EventTarget` interface (`addEventListener`, `removeEventListener`). It also doesn't support the `upload` object on Android -- for no good reason. Even if we don't send any events there yet, there's no reason we have to break consuming code that wants to register an event handler there. This PR rectifies all that.
Fortunately, adding proper `EventTarget` support is very easy thanks to `event-target-shim`. We already use it in our WebSocket implementation. It transparently handles the `addEventListener('foo', ...)` as well as `onfoo` APIs, so when you dispatch an event on the event target, the right handlers will be invoked. The event object is wrapped so that `event.target` is set properly. Basically, it's a super easy way to make us conform to the spec.
Also added a bit of polish here and there, using ES2015 class property goodness to consolidate a lot of Flow property definitions with the corresponding property initializers.
**T
Closes https://github.com/facebook/react-native/pull/7017
Reviewed By: fkgozali
Differential Revision: D3202021
Pulled By: martinbigio
fb-gh-sync-id: 2b007682074356c75c774fab337672918b6c4355
fbshipit-source-id: 2b007682074356c75c774fab337672918b6c4355
2016-04-28 22:58:25 +00:00
|
|
|
super.addEventListener(type, listener);
|
2015-03-24 21:40:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-17 07:58:49 +00:00
|
|
|
|
2016-04-11 12:53:41 +00:00
|
|
|
function toArrayBuffer(text: string, contentType: string): ArrayBuffer {
|
|
|
|
const {length} = text;
|
|
|
|
if (length === 0) {
|
|
|
|
return new ArrayBuffer(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
const charsetMatch = contentType.match(/;\s*charset=([^;]*)/i);
|
|
|
|
const charset = charsetMatch ? charsetMatch[1].trim() : 'utf-8';
|
|
|
|
|
|
|
|
if (/^utf-?8$/i.test(charset)) {
|
|
|
|
return utf8.encode(text);
|
|
|
|
} else { //TODO: utf16 / ucs2 / utf32
|
|
|
|
const array = new Uint8Array(length);
|
|
|
|
for (let i = 0; i < length; i++) {
|
|
|
|
array[i] = text.charCodeAt(i); // Uint8Array automatically masks with 0xff
|
|
|
|
}
|
|
|
|
return array.buffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-25 11:17:35 +00:00
|
|
|
module.exports = XMLHttpRequest;
|