From 40d71e6c5bd02a391e8f1ce1db0471247aee427f Mon Sep 17 00:00:00 2001 From: Olivia Bishop Date: Tue, 24 Mar 2015 14:40:11 -0700 Subject: [PATCH] JS files from D1936817: Add to XMLHttpRequest android and share code with ios --- Libraries/Network/XMLHttpRequest.ios.js | 139 ++------------------- Libraries/Network/XMLHttpRequestBase.js | 153 ++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 130 deletions(-) create mode 100644 Libraries/Network/XMLHttpRequestBase.js diff --git a/Libraries/Network/XMLHttpRequest.ios.js b/Libraries/Network/XMLHttpRequest.ios.js index f5cc42eef..2287ee7b2 100644 --- a/Libraries/Network/XMLHttpRequest.ios.js +++ b/Libraries/Network/XMLHttpRequest.ios.js @@ -15,153 +15,32 @@ var RCTDataManager = require('NativeModules').DataManager; var crc32 = require('crc32'); -class XMLHttpRequest { +var XMLHttpRequestBase = require('XMLHttpRequestBase'); - UNSENT: number; - OPENED: number; - HEADERS_RECEIVED: number; - LOADING: number; - DONE: number; - - onreadystatechange: ?Function; - onload: ?Function; - upload: any; - readyState: number; - responseHeaders: ?Object; - responseText: ?string; - status: ?string; - - _method: ?string; - _url: ?string; - _headers: Object; - _sent: boolean; - _aborted: boolean; - - constructor() { - this.UNSENT = 0; - this.OPENED = 1; - this.HEADERS_RECEIVED = 2; - this.LOADING = 3; - this.DONE = 4; - - this.onreadystatechange = undefined; - this.upload = undefined; /* Upload not supported */ - this.readyState = this.UNSENT; - this.responseHeaders = undefined; - this.responseText = undefined; - this.status = undefined; - - this._method = null; - this._url = null; - this._headers = {}; - this._sent = false; - this._aborted = false; - } - - getAllResponseHeaders(): ?string { - /* Stub */ - return ''; - } - - getResponseHeader(header: string): ?string { - /* Stub */ - return ''; - } - - setRequestHeader(header: string, value: any): void { - this._headers[header] = value; - } - - open(method: string, url: string, async: ?boolean): void { - /* Other optional arguments are not supported */ - 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'); - } - this._method = method; - this._url = url; - this._aborted = false; - this._setReadyState(this.OPENED); - } - - 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; +class XMLHttpRequest extends XMLHttpRequestBase { + sendImpl(method: ?string, url: ?string, headers: Object, data: any): void { RCTDataManager.queryData( 'http', JSON.stringify({ - method: this._method, - url: this._url, + method: method, + url: url, data: data, - headers: this._headers, + headers: headers, }), - 'h' + crc32(this._method + '|' + this._url + '|' + data), + 'h' + crc32(method + '|' + url + '|' + data), (result) => { result = JSON.parse(result); - this._callback(result.status, result.responseHeaders, result.responseText); + this.callback(result.status, result.responseHeaders, result.responseText); } ); } - abort(): void { + abortImpl(): void { console.warn( 'XMLHttpRequest: abort() cancels JS callbacks ' + 'but not native HTTP request.' ); - // 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)) { - this._sent = false; - this._setReadyState(this.DONE); - } - if (this.readyState === this.DONE) { - this._sendLoad(); - } - this.readyState = this.UNSENT; - this._aborted = true; - } - - _setReadyState(newState: number): void { - this.readyState = newState; - // TODO: workaround flow bug with nullable function checks - var onreadystatechange = this.onreadystatechange; - if (onreadystatechange) { - // We should send an event to handler, but since we don't process that - // event anywhere, let's leave it empty - onreadystatechange(null); - } - } - - _sendLoad(): void { - // TODO: workaround flow bug with nullable function checks - var onload = this.onload; - if (onload) { - // We should send an event to handler, but since we don't process that - // event anywhere, let's leave it empty - onload(null); - } - } - - _callback(status: string, responseHeaders: ?Object, responseText: string): void { - if (this._aborted) { - return; - } - this.status = status; - this.responseHeaders = responseHeaders; - this.responseText = responseText; - this._setReadyState(this.DONE); - this._sendLoad(); } } diff --git a/Libraries/Network/XMLHttpRequestBase.js b/Libraries/Network/XMLHttpRequestBase.js new file mode 100644 index 000000000..d7619d075 --- /dev/null +++ b/Libraries/Network/XMLHttpRequestBase.js @@ -0,0 +1,153 @@ +/** + * Copyright 2004-present Facebook. All Rights Reserved. + * + * @flow + * @providesModule XMLHttpRequestBase + */ +'use strict'; + +/** + * Shared base for platform-specific XMLHttpRequest implementations. + */ +class XMLHttpRequestBase { + + UNSENT: number; + OPENED: number; + HEADERS_RECEIVED: number; + LOADING: number; + DONE: number; + + onreadystatechange: ?Function; + onload: ?Function; + upload: any; + readyState: number; + responseHeaders: ?Object; + responseText: ?string; + status: ?string; + + _method: ?string; + _url: ?string; + _headers: Object; + _sent: boolean; + _aborted: boolean; + + constructor() { + this.UNSENT = 0; + this.OPENED = 1; + this.HEADERS_RECEIVED = 2; + this.LOADING = 3; + this.DONE = 4; + + this.onreadystatechange = undefined; + this.upload = undefined; /* Upload not supported */ + this.readyState = this.UNSENT; + this.responseHeaders = undefined; + this.responseText = undefined; + this.status = undefined; + + this._method = null; + this._url = null; + this._headers = {}; + this._sent = false; + this._aborted = false; + } + + getAllResponseHeaders(): ?string { + /* Stub */ + return ''; + } + + getResponseHeader(header: string): ?string { + /* Stub */ + return ''; + } + + setRequestHeader(header: string, value: any): void { + this._headers[header] = value; + } + + open(method: string, url: string, async: ?boolean): void { + /* Other optional arguments are not supported */ + 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'); + } + this._method = method; + this._url = url; + this._aborted = false; + this._setReadyState(this.OPENED); + } + + sendImpl(method: ?string, url: ?string, headers: Object, data: any): void { + throw new Error('Subclass must define sendImpl method'); + } + + abortImpl(): void { + throw new Error('Subclass must define abortImpl method'); + } + + 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; + this.sendImpl(this._method, this._url, this._headers, data); + } + + abort(): void { + this.abortImpl(); + // 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)) { + this._sent = false; + this._setReadyState(this.DONE); + } + if (this.readyState === this.DONE) { + this._sendLoad(); + } + this.readyState = this.UNSENT; + this._aborted = true; + } + + callback(status: string, responseHeaders: ?Object, responseText: string): void { + if (this._aborted) { + return; + } + this.status = status; + this.responseHeaders = responseHeaders; + this.responseText = responseText; + this._setReadyState(this.DONE); + this._sendLoad(); + } + + _setReadyState(newState: number): void { + this.readyState = newState; + // TODO: workaround flow bug with nullable function checks + var onreadystatechange = this.onreadystatechange; + if (onreadystatechange) { + // We should send an event to handler, but since we don't process that + // event anywhere, let's leave it empty + onreadystatechange(null); + } + } + + _sendLoad(): void { + // TODO: workaround flow bug with nullable function checks + var onload = this.onload; + if (onload) { + // We should send an event to handler, but since we don't process that + // event anywhere, let's leave it empty + onload(null); + } + } +} + +module.exports = XMLHttpRequestBase;