Skip to content

Commit

Permalink
XMLHttpRequest should dispatch loadend events
Browse files Browse the repository at this point in the history
Summary:
The code was never dispatching the loadend event. The event should be
dispatched after the load, error, timeout and abort events (abort
events are not yet supported).

https://xhr.spec.whatwg.org/#event-xhr-loadend
Closes #10047

Differential Revision: D3911080

fbshipit-source-id: 450f50a6f2a5c6845889bce624c64a1ca47ec06b
  • Loading branch information
arv authored and Facebook Github Bot 9 committed Sep 23, 2016
1 parent 2da0888 commit 04d870b
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
7 changes: 5 additions & 2 deletions Libraries/Network/XMLHttpRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,10 @@ class XMLHttpRequest extends EventTarget(...XHR_EVENTS) {
setReadyState(newState: number): void {
this.readyState = newState;
this.dispatchEvent({type: 'readystatechange'});
if (newState === this.DONE && !this._aborted) {
if (this._hasError) {
if (newState === this.DONE) {
if (this._aborted) {
this.dispatchEvent({type: 'abort'});
} else if (this._hasError) {
if (this._timedOut) {
this.dispatchEvent({type: 'timeout'});
} else {
Expand All @@ -478,6 +480,7 @@ class XMLHttpRequest extends EventTarget(...XHR_EVENTS) {
} else {
this.dispatchEvent({type: 'load'});
}
this.dispatchEvent({type: 'loadend'});
}
}

Expand Down
14 changes: 13 additions & 1 deletion Libraries/Network/__tests__/XMLHttpRequest-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,27 @@ describe('XMLHttpRequest', function() {
var handleError;
var handleLoad;
var handleReadyStateChange;
var handleLoadEnd;

beforeEach(() => {
xhr = new XMLHttpRequest();

xhr.ontimeout = jest.fn();
xhr.onerror = jest.fn();
xhr.onload = jest.fn();
xhr.onloadend = jest.fn();
xhr.onreadystatechange = jest.fn();

handleTimeout = jest.fn();
handleError = jest.fn();
handleLoad = jest.fn();
handleLoadEnd = jest.fn();
handleReadyStateChange = jest.fn();

xhr.addEventListener('timeout', handleTimeout);
xhr.addEventListener('error', handleError);
xhr.addEventListener('load', handleLoad);
xhr.addEventListener('loadend', handleLoadEnd);
xhr.addEventListener('readystatechange', handleReadyStateChange);
});

Expand All @@ -58,6 +62,8 @@ describe('XMLHttpRequest', function() {
handleTimeout = null;
handleError = null;
handleLoad = null;
handleLoadEnd = null;
handleReadyStateChange = null;
});

it('should transition readyState correctly', function() {
Expand Down Expand Up @@ -119,10 +125,12 @@ describe('XMLHttpRequest', function() {
expect(xhr.readyState).toBe(xhr.DONE);

expect(xhr.ontimeout.mock.calls.length).toBe(1);
expect(xhr.onloadend.mock.calls.length).toBe(1);
expect(xhr.onerror).not.toBeCalled();
expect(xhr.onload).not.toBeCalled();

expect(handleTimeout.mock.calls.length).toBe(1);
expect(handleLoadEnd.mock.calls.length).toBe(1);
expect(handleError).not.toBeCalled();
expect(handleLoad).not.toBeCalled();
});
Expand All @@ -136,11 +144,13 @@ describe('XMLHttpRequest', function() {

expect(xhr.onreadystatechange.mock.calls.length).toBe(2);
expect(xhr.onerror.mock.calls.length).toBe(1);
expect(xhr.onloadend.mock.calls.length).toBe(1);
expect(xhr.ontimeout).not.toBeCalled();
expect(xhr.onload).not.toBeCalled();

expect(handleReadyStateChange.mock.calls.length).toBe(2);
expect(handleError.mock.calls.length).toBe(1);
expect(handleLoadEnd.mock.calls.length).toBe(1);
expect(handleTimeout).not.toBeCalled();
expect(handleLoad).not.toBeCalled();
});
Expand All @@ -154,16 +164,18 @@ describe('XMLHttpRequest', function() {

expect(xhr.onreadystatechange.mock.calls.length).toBe(2);
expect(xhr.onload.mock.calls.length).toBe(1);
expect(xhr.onloadend.mock.calls.length).toBe(1);
expect(xhr.onerror).not.toBeCalled();
expect(xhr.ontimeout).not.toBeCalled();

expect(handleReadyStateChange.mock.calls.length).toBe(2);
expect(handleLoad.mock.calls.length).toBe(1);
expect(handleLoadEnd.mock.calls.length).toBe(1);
expect(handleError).not.toBeCalled();
expect(handleTimeout).not.toBeCalled();
});

it('should call onload function when there is no error', function() {
it('should call upload onprogress', function() {
xhr.open('GET', 'blabla');
xhr.send();

Expand Down

0 comments on commit 04d870b

Please sign in to comment.