From 04d870b10b94ef9dc9cee8824ce373f61a887151 Mon Sep 17 00:00:00 2001 From: Erik Arvidsson Date: Thu, 22 Sep 2016 17:07:56 -0700 Subject: [PATCH] XMLHttpRequest should dispatch loadend events 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 https://github.com/facebook/react-native/pull/10047 Differential Revision: D3911080 fbshipit-source-id: 450f50a6f2a5c6845889bce624c64a1ca47ec06b --- Libraries/Network/XMLHttpRequest.js | 7 +++++-- Libraries/Network/__tests__/XMLHttpRequest-test.js | 14 +++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Libraries/Network/XMLHttpRequest.js b/Libraries/Network/XMLHttpRequest.js index 793a9c13cef068..28a228ccd1fe2a 100644 --- a/Libraries/Network/XMLHttpRequest.js +++ b/Libraries/Network/XMLHttpRequest.js @@ -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 { @@ -478,6 +480,7 @@ class XMLHttpRequest extends EventTarget(...XHR_EVENTS) { } else { this.dispatchEvent({type: 'load'}); } + this.dispatchEvent({type: 'loadend'}); } } diff --git a/Libraries/Network/__tests__/XMLHttpRequest-test.js b/Libraries/Network/__tests__/XMLHttpRequest-test.js index fbc0bbe36fcf5e..2f343a8fe7eb70 100644 --- a/Libraries/Network/__tests__/XMLHttpRequest-test.js +++ b/Libraries/Network/__tests__/XMLHttpRequest-test.js @@ -33,6 +33,7 @@ describe('XMLHttpRequest', function() { var handleError; var handleLoad; var handleReadyStateChange; + var handleLoadEnd; beforeEach(() => { xhr = new XMLHttpRequest(); @@ -40,16 +41,19 @@ describe('XMLHttpRequest', function() { 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); }); @@ -58,6 +62,8 @@ describe('XMLHttpRequest', function() { handleTimeout = null; handleError = null; handleLoad = null; + handleLoadEnd = null; + handleReadyStateChange = null; }); it('should transition readyState correctly', function() { @@ -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(); }); @@ -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(); }); @@ -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();