From d3c987f827a45924e15dfd9bd7b6026263d30e05 Mon Sep 17 00:00:00 2001 From: Vladimir Enchev Date: Mon, 20 Jul 2015 10:58:29 +0300 Subject: [PATCH 1/5] XMLHttpRequest separated from http module --- CrossPlatformModules.csproj | 6 + apps/tests/http-tests.ts | 182 +-------------------------- apps/tests/testRunner.ts | 1 + apps/tests/xhr-tests.ts | 183 ++++++++++++++++++++++++++++ globals/globals.ts | 4 +- http/http.ts | 236 +----------------------------------- xhr/Readme.md | 1 + xhr/package.json | 2 + xhr/xhr.ts | 228 ++++++++++++++++++++++++++++++++++ 9 files changed, 429 insertions(+), 414 deletions(-) create mode 100644 apps/tests/xhr-tests.ts create mode 100644 xhr/Readme.md create mode 100644 xhr/package.json create mode 100644 xhr/xhr.ts diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj index 4ccb31161..a0a81df7a 100644 --- a/CrossPlatformModules.csproj +++ b/CrossPlatformModules.csproj @@ -182,6 +182,7 @@ + @@ -1032,6 +1033,7 @@ + @@ -1688,6 +1690,10 @@ PreserveNewest + + PreserveNewest + + diff --git a/apps/tests/http-tests.ts b/apps/tests/http-tests.ts index 58abade52..15e125b7d 100644 --- a/apps/tests/http-tests.ts +++ b/apps/tests/http-tests.ts @@ -110,7 +110,7 @@ export var test_getImage = function (done) { // // ### Get Image from URL // ``` JavaScript - http.getImage("http://www.google.com/images/errors/logo_sm_2.png").then(function (r) { + http.getImage("https://httpbin.org/image/png").then(function (r) { //// Argument (r) is Image! // result = r; @@ -309,7 +309,7 @@ export var test_request_responseContentToJSONShouldReturnJSON = function (done) export var test_request_responseContentToImageShouldReturnCorrectImage = function (done) { var result; - http.request({ url: "http://www.google.com/images/errors/logo_sm_2.png", method: "GET" }).then(function (response) { + http.request({ url: "https://httpbin.org/image/png", method: "GET" }).then(function (response) { response.content.toImage().then((source) => { result = source; try { @@ -452,180 +452,4 @@ function doRequest(url: string, done: Function) { }, function (e) { done(e); }); -} - -export var test_XMLHttpRequest_isDefined = function () { - TKUnit.assert(types.isDefined(global["XMLHttpRequest"]), "XMLHttpRequest should be defined!"); -}; - -var xhr = new XMLHttpRequest(); - -export var test_XMLHttpRequest_open_isDefined = function () { - TKUnit.assert(types.isFunction(xhr.open), "XMLHttpRequest.open should be defined!"); -}; - -export var test_XMLHttpRequest_send_isDefined = function () { - TKUnit.assert(types.isFunction(xhr.send), "XMLHttpRequest.send should be defined!"); -}; - -export var test_XMLHttpRequest_setRequestHeader_isDefined = function () { - TKUnit.assert(types.isFunction(xhr.setRequestHeader), "XMLHttpRequest.setRequestHeader should be defined!"); -}; - -export var test_XMLHttpRequest_getAllResponseHeaders_isDefined = function () { - TKUnit.assert(types.isFunction(xhr.getAllResponseHeaders), "XMLHttpRequest.getAllResponseHeaders should be defined!"); -}; - -export var test_XMLHttpRequest_getResponseHeader_isDefined = function () { - TKUnit.assert(types.isFunction(xhr.getResponseHeader), "XMLHttpRequest.getResponseHeader should be defined!"); -}; - -export var test_XMLHttpRequest_overrideMimeType_isDefined = function () { - TKUnit.assert(types.isFunction(xhr.overrideMimeType), "XMLHttpRequest.overrideMimeType should be defined!"); -}; - -export var test_XMLHttpRequest_readyState_isDefined = function () { - TKUnit.assert(types.isDefined(xhr.readyState), "XMLHttpRequest.readyState should be defined!"); -}; - -export var test_XMLHttpRequest_responseText_isDefined = function () { - TKUnit.assert(types.isDefined(xhr.responseText), "XMLHttpRequest.responseText should be defined!"); -}; - -export var test_XMLHttpRequest_readyStateShouldChange = function (done) { - var count = 0; - xhr = new XMLHttpRequest(); - - TKUnit.assert(xhr.readyState === 0, "xhr.readyState should be UNSENT!"); - - xhr.onreadystatechange = function () { - try { - - if (count === 0) { - TKUnit.assert(xhr.readyState === 1, "xhr.readyState should be OPEN!"); - } else if (count === 1) { - TKUnit.assert(xhr.readyState === 2, "xhr.readyState should be HEADERS_RECEIVED!"); - } else if (count === 2) { - TKUnit.assert(xhr.readyState === 3, "xhr.readyState should be LOADING!"); - } else if (count === 3) { - TKUnit.assert(xhr.readyState === 4, "xhr.readyState should be DONE!"); - } - - count++; - - done(null); - } - catch (err) { - done(err); - } - }; - - xhr.open("GET", "https://httpbin.org/get"); - xhr.send(); -}; - -export var test_XMLHttpRequest_headersSentAndReceivedProperly = function (done) { - xhr = new XMLHttpRequest(); - xhr.open("GET", "https://httpbin.org/get"); - xhr.setRequestHeader("Content-Type", "application/json"); - xhr.onreadystatechange = function () { - if (xhr.readyState > 1) { - try { - TKUnit.assert(xhr.getResponseHeader("Content-Type") === "application/json", "Headers not sent/received properly!"); - done(null); - } - catch (err) { - done(err); - } - } - }; - xhr.send(); -}; - -export var test_XMLHttpRequest_contentSentAndReceivedProperly = function (done) { - xhr = new XMLHttpRequest(); - xhr.open("POST", "https://httpbin.org/post"); - xhr.setRequestHeader("Content-Type", "application/json"); - xhr.onreadystatechange = function () { - if (xhr.readyState > 3) { - var result = JSON.parse(xhr.responseText); - try { - TKUnit.assert(result["json"]["MyVariableOne"] === "ValueOne" && result["json"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!"); - done(null); - } - catch (err) { - done(err); - } - } - }; - xhr.send(JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" })); -}; - -export var test_XMLHttpRequest_abortShouldCancelonreadystatechange = function (done) { - var flag = false; - - xhr = new XMLHttpRequest(); - xhr.open("POST", "https://httpbin.org/post"); - xhr.setRequestHeader("Content-Type", "application/json"); - xhr.onreadystatechange = function () { - flag = true; - }; - xhr.send(JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" })); - xhr.abort(); - - TKUnit.assert(flag === false, "Content not sent/received properly!"); - done(null); -}; - -export var test_XMLHttpRequest_requestShouldBePossibleAfterAbort = function (done) { - xhr = new XMLHttpRequest(); - xhr.open("POST", "https://httpbin.org/post"); - xhr.setRequestHeader("Content-Type", "application/json"); - xhr.onreadystatechange = function () { - if (xhr.readyState > 3) { - var result = JSON.parse(xhr.responseText); - try { - TKUnit.assert(result["json"]["MyVariableOne"] === "ValueOne" && result["json"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!"); - done(null); - } - catch (err) { - done(err); - } - } - }; - xhr.send(JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" })); - xhr.abort(); - - xhr.send(JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" })); -}; - -export function test_raises_onload_Event(done) { - let xhr = new XMLHttpRequest(); - xhr.onload = () => { - done(null); - } - xhr.open("GET", "https://httpbin.org/get"); - xhr.send(); -} - -export function test_raises_onerror_Event(done) { - let xhr = new XMLHttpRequest(); - xhr.onerror = () => { - done(null); - } - xhr.open("GET", "https://no-such-domain-httpbin.org"); - xhr.send(); -} - -export function test_responseType(done) { - let xhr = new XMLHttpRequest(); - xhr.responseType = ""; - xhr.responseType = "text"; - - TKUnit.assertThrows( - () => xhr.responseType = "json", - "Didn't raise on unsupported type.", - "Response type of 'json' not supported." - ); - done(null); -} +} \ No newline at end of file diff --git a/apps/tests/testRunner.ts b/apps/tests/testRunner.ts index d38d8f33e..63178d4f5 100644 --- a/apps/tests/testRunner.ts +++ b/apps/tests/testRunner.ts @@ -36,6 +36,7 @@ allTests["STYLE-PROPERTIES"] = require("./ui/style/style-properties-tests"); allTests["SCROLL-VIEW"] = require("./ui/scroll-view/scroll-view-tests"); allTests["FILE SYSTEM"] = require("./file-system-tests"); allTests["HTTP"] = require("./http-tests"); +allTests["XHR"] = require("./xhr-tests"); allTests["FETCH"] = require("./fetch-tests"); allTests["APPLICATION SETTINGS"] = require("./application-settings-tests"); allTests["IMAGE SOURCE"] = require("./image-source-tests"); diff --git a/apps/tests/xhr-tests.ts b/apps/tests/xhr-tests.ts new file mode 100644 index 000000000..3836be4a3 --- /dev/null +++ b/apps/tests/xhr-tests.ts @@ -0,0 +1,183 @@ +/* tslint:disable:no-unused-variable */ +import TKUnit = require("./TKUnit"); +import types = require("utils/types"); + +export var test_XMLHttpRequest_isDefined = function () { + TKUnit.assert(types.isDefined(global["XMLHttpRequest"]), "XMLHttpRequest should be defined!"); +}; + +var xhr = new XMLHttpRequest(); + +export var test_XMLHttpRequest_open_isDefined = function () { + TKUnit.assert(types.isFunction(xhr.open), "XMLHttpRequest.open should be defined!"); +}; + +export var test_XMLHttpRequest_send_isDefined = function () { + TKUnit.assert(types.isFunction(xhr.send), "XMLHttpRequest.send should be defined!"); +}; + +export var test_XMLHttpRequest_setRequestHeader_isDefined = function () { + TKUnit.assert(types.isFunction(xhr.setRequestHeader), "XMLHttpRequest.setRequestHeader should be defined!"); +}; + +export var test_XMLHttpRequest_getAllResponseHeaders_isDefined = function () { + TKUnit.assert(types.isFunction(xhr.getAllResponseHeaders), "XMLHttpRequest.getAllResponseHeaders should be defined!"); +}; + +export var test_XMLHttpRequest_getResponseHeader_isDefined = function () { + TKUnit.assert(types.isFunction(xhr.getResponseHeader), "XMLHttpRequest.getResponseHeader should be defined!"); +}; + +export var test_XMLHttpRequest_overrideMimeType_isDefined = function () { + TKUnit.assert(types.isFunction(xhr.overrideMimeType), "XMLHttpRequest.overrideMimeType should be defined!"); +}; + +export var test_XMLHttpRequest_readyState_isDefined = function () { + TKUnit.assert(types.isNumber(xhr.readyState), "XMLHttpRequest.readyState should be defined!"); +}; + +export var test_XMLHttpRequest_responseText_isDefined = function () { + TKUnit.assert(types.isString(xhr.responseText), "XMLHttpRequest.responseText should be defined!"); +}; + +export var test_XMLHttpRequest_responseType_isDefined = function () { + TKUnit.assert(types.isString(xhr.responseType), "XMLHttpRequest.responseType should be defined!"); +}; + +export var test_XMLHttpRequest_readyStateShouldChange = function (done) { + var count = 0; + xhr = new XMLHttpRequest(); + + TKUnit.assert(xhr.readyState === 0, "xhr.readyState should be UNSENT!"); + + xhr.onreadystatechange = function () { + try { + + if (count === 0) { + TKUnit.assert(xhr.readyState === 1, "xhr.readyState should be OPEN!"); + } else if (count === 1) { + TKUnit.assert(xhr.readyState === 2, "xhr.readyState should be HEADERS_RECEIVED!"); + } else if (count === 2) { + TKUnit.assert(xhr.readyState === 3, "xhr.readyState should be LOADING!"); + } else if (count === 3) { + TKUnit.assert(xhr.readyState === 4, "xhr.readyState should be DONE!"); + } + + count++; + + done(null); + } + catch (err) { + done(err); + } + }; + + xhr.open("GET", "https://httpbin.org/get"); + xhr.send(); +}; + +export var test_XMLHttpRequest_headersSentAndReceivedProperly = function (done) { + xhr = new XMLHttpRequest(); + xhr.open("GET", "https://httpbin.org/get"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.onreadystatechange = function () { + if (xhr.readyState > 1) { + try { + TKUnit.assert(xhr.getResponseHeader("Content-Type") === "application/json", "Headers not sent/received properly!"); + done(null); + } + catch (err) { + done(err); + } + } + }; + xhr.send(); +}; + +export var test_XMLHttpRequest_contentSentAndReceivedProperly = function (done) { + xhr = new XMLHttpRequest(); + xhr.open("POST", "https://httpbin.org/post"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.onreadystatechange = function () { + if (xhr.readyState > 3) { + var result = JSON.parse(xhr.responseText); + try { + TKUnit.assert(result["json"]["MyVariableOne"] === "ValueOne" && result["json"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!"); + done(null); + } + catch (err) { + done(err); + } + } + }; + xhr.send(JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" })); +}; + +export var test_XMLHttpRequest_abortShouldCancelonreadystatechange = function (done) { + var flag = false; + + xhr = new XMLHttpRequest(); + xhr.open("POST", "https://httpbin.org/post"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.onreadystatechange = function () { + flag = true; + }; + xhr.send(JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" })); + xhr.abort(); + + TKUnit.assert(flag === false, "Content not sent/received properly!"); + done(null); +}; + +export var test_XMLHttpRequest_requestShouldBePossibleAfterAbort = function (done) { + xhr = new XMLHttpRequest(); + xhr.open("POST", "https://httpbin.org/post"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.onreadystatechange = function () { + if (xhr.readyState > 3) { + var result = JSON.parse(xhr.responseText); + try { + TKUnit.assert(result["json"]["MyVariableOne"] === "ValueOne" && result["json"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!"); + done(null); + } + catch (err) { + done(err); + } + } + }; + xhr.send(JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" })); + xhr.abort(); + + xhr.send(JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" })); +}; + +export function test_raises_onload_Event(done) { + let xhr = new XMLHttpRequest(); + xhr.onload = () => { + done(null); + } + xhr.open("GET", "https://httpbin.org/get"); + xhr.send(); +} + +export function test_raises_onerror_Event(done) { + let xhr = new XMLHttpRequest(); + xhr.onerror = () => { + done(null); + } + xhr.open("GET", "https://no-such-domain-httpbin.org"); + xhr.send(); +} + +export function test_responseType(done) { + let xhr = new XMLHttpRequest(); + xhr.responseType = ""; + xhr.responseType = "text"; + + TKUnit.assertThrows( + () => xhr.responseType = "json", + "Didn't raise on unsupported type.", + "Response type of 'json' not supported." + ); + done(null); +} diff --git a/globals/globals.ts b/globals/globals.ts index 28a960fb7..86d704e85 100644 --- a/globals/globals.ts +++ b/globals/globals.ts @@ -1,7 +1,7 @@ import types = require("utils/types"); import timer = require("timer"); import consoleModule = require("console"); -import http = require("http"); +import xhr = require("xhr/xhr"); import dialogs = require("ui/dialogs"); global.setTimeout = timer.setTimeout; @@ -14,7 +14,7 @@ if (types.isUndefined(global.NSObject)) { global.console = new consoleModule.Console(); } -global.XMLHttpRequest = (http).XMLHttpRequest; +global.XMLHttpRequest = xhr.XMLHttpRequest; global.alert = dialogs.alert; export function Deprecated(target: Object, key?: string | symbol, descriptor?: any) { diff --git a/http/http.ts b/http/http.ts index 0e9a22ef2..c6f2f6c40 100644 --- a/http/http.ts +++ b/http/http.ts @@ -1,10 +1,6 @@ import image = require("image-source"); - -import definition = require("http"); import httpRequest = require("http/http-request"); -import types = require("utils/types"); - // merge the exports of the request file with the exports of this file declare var exports; require("utils/module-merge").merge(httpRequest, exports); @@ -27,233 +23,7 @@ export function getImage(arg: any): Promise { return new Promise((resolve, reject) => { httpRequest.request(typeof arg === "string" ? { url: arg, method: "GET" } : arg) .then(r => { - r.content.toImage().then(source => resolve(source)); - }, e => reject(e)); + r.content.toImage().then(source => resolve(source)); + }, e => reject(e)); }); -} - -export class XMLHttpRequest { - public UNSENT = 0; - public OPENED = 1; - public HEADERS_RECEIVED = 2; - public LOADING = 3; - public DONE = 4; - - public onload: () => void; - public onerror: () => void; - - private _options: definition.HttpRequestOptions; - private _readyState: number; - private _status: number; - private _response: any; - private _responseText: string = ""; - private _headers: any; - private _errorFlag: boolean; - private _responseType: string; - - public onreadystatechange: Function; - - constructor() { - this._readyState = this.UNSENT; - } - - public open(method: string, url: string, async?: boolean, user?: string, password?: string) { - if (types.isString(method) && types.isString(url)) { - this._options = { url: url, method: method }; - this._options.headers = {}; - - if (types.isString(user)) { - this._options.headers["user"] = user; - } - - if (types.isString(password)) { - this._options.headers["password"] = password; - } - - this._setReadyState(this.OPENED); - } - } - - public abort() { - this._errorFlag = true; - - this._response = null; - this._responseText = null; - this._headers = null; - this._status = null; - - if (this._readyState === this.UNSENT || this._readyState === this.OPENED || this._readyState === this.DONE) { - this._readyState = this.UNSENT; - } else { - this._setReadyState(this.DONE); - } - } - - public send(data?: string) { - this._errorFlag = false; - this._response = null; - this._responseText = null; - this._headers = null; - this._status = null; - - if (types.isDefined(this._options)) { - if (types.isString(data)) { - this._options.content = data; - } - - httpRequest.request(this._options).then(r=> { - if (!this._errorFlag) { - this._status = r.statusCode; - this._response = r.content.raw; - - this._headers = r.headers; - this._setReadyState(this.HEADERS_RECEIVED); - - this._setReadyState(this.LOADING); - - this._responseText = r.content.toString(); - this._setReadyState(this.DONE); - } - - }).catch(e => { - this._errorFlag = true; - this._setReadyState(this.DONE); - }); - } - } - - public setRequestHeader(header: string, value: string) { - if (types.isDefined(this._options) && types.isString(header) && types.isString(value)) { - this._options.headers[header] = value; - } - } - - public getAllResponseHeaders(): string { - if (this._readyState < 2 || this._errorFlag) { - return ""; - } - - var result = ""; - - for (var i in this._headers) { - // Cookie headers are excluded - if (i !== "set-cookie" && i !== "set-cookie2") { - result += i + ": " + this._headers[i] + "\r\n"; - } - } - return result.substr(0, result.length - 2); - } - - public getResponseHeader(header: string): string { - if (types.isString(header) && this._readyState > 1 - && this._headers - && this._headers[header] - && !this._errorFlag - ) { - return this._headers[header]; - } - - return null; - } - - public overrideMimeType(mime: string) { - // - } - - get readyState(): number { - return this._readyState; - } - - public get responseType(): string { - return this._responseType; - } - - public set responseType(value: string) { - if (value === "" || value === "text") { - this._responseType = value; - } else { - throw new Error(`Response type of '${value}' not supported.`); - } - } - - private _setReadyState(value: number) { - if (this._readyState !== value) { - this._readyState = value; - - if (types.isFunction(this.onreadystatechange)) { - this.onreadystatechange(); - } - } - - if (this._readyState === this.DONE) { - if (this._errorFlag && types.isFunction(this.onerror)) { - this.onerror(); - } - if (!this._errorFlag && types.isFunction(this.onload)) { - this.onload(); - } - } - } - - get responseText(): string { - return this._responseText; - } - - get response(): any { - return this._response; - } - - get status(): number { - return this._status; - } - - get statusText(): string { - if (this._readyState === this.UNSENT || this._readyState === this.OPENED || this._errorFlag) { - return ""; - } - return this._status + " " + statuses[this._status]; - } -} - -var statuses = { - 100: "Continue", - 101: "Switching Protocols", - 200: "OK", - 201: "Created", - 202: "Accepted", - 203: "Non - Authoritative Information", - 204: "No Content", - 205: "Reset Content", - 206: "Partial Content", - 300: "Multiple Choices", - 301: "Moved Permanently", - 302: "Found", - 303: "See Other", - 304: "Not Modified", - 305: "Use Proxy", - 307: "Temporary Redirect", - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Request Entity Too Large", - 414: "Request - URI Too Long", - 415: "Unsupported Media Type", - 416: "Requested Range Not Satisfiable", - 417: "Expectation Failed", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported" -}; +} \ No newline at end of file diff --git a/xhr/Readme.md b/xhr/Readme.md new file mode 100644 index 000000000..b613b64a2 --- /dev/null +++ b/xhr/Readme.md @@ -0,0 +1 @@ +XMLHttpRequest Level 2: https://xhr.spec.whatwg.org/ \ No newline at end of file diff --git a/xhr/package.json b/xhr/package.json new file mode 100644 index 000000000..cc5d20cf3 --- /dev/null +++ b/xhr/package.json @@ -0,0 +1,2 @@ +{ "name" : "xhr", + "main" : "xhr.js" } \ No newline at end of file diff --git a/xhr/xhr.ts b/xhr/xhr.ts new file mode 100644 index 000000000..7e2c5ef05 --- /dev/null +++ b/xhr/xhr.ts @@ -0,0 +1,228 @@ +import http = require("http"); +import types = require("utils/types"); + +export class XMLHttpRequest { + public UNSENT = 0; + public OPENED = 1; + public HEADERS_RECEIVED = 2; + public LOADING = 3; + public DONE = 4; + + public onload: () => void; + public onerror: () => void; + + private _options: http.HttpRequestOptions; + private _readyState: number; + private _status: number; + private _response: any; + private _responseText: string = ""; + private _headers: any; + private _errorFlag: boolean; + private _responseType: string = ""; + + public onreadystatechange: Function; + + constructor() { + this._readyState = this.UNSENT; + } + + public open(method: string, url: string, async?: boolean, user?: string, password?: string) { + if (types.isString(method) && types.isString(url)) { + this._options = { url: url, method: method }; + this._options.headers = {}; + + if (types.isString(user)) { + this._options.headers["user"] = user; + } + + if (types.isString(password)) { + this._options.headers["password"] = password; + } + + this._setReadyState(this.OPENED); + } + } + + public abort() { + this._errorFlag = true; + + this._response = null; + this._responseText = null; + this._headers = null; + this._status = null; + + if (this._readyState === this.UNSENT || this._readyState === this.OPENED || this._readyState === this.DONE) { + this._readyState = this.UNSENT; + } else { + this._setReadyState(this.DONE); + } + } + + public send(data?: string) { + this._errorFlag = false; + this._response = null; + this._responseText = null; + this._headers = null; + this._status = null; + + if (types.isDefined(this._options)) { + if (types.isString(data)) { + this._options.content = data; + } + + http.request(this._options).then(r=> { + if (!this._errorFlag) { + this._status = r.statusCode; + this._response = r.content.raw; + + this._headers = r.headers; + this._setReadyState(this.HEADERS_RECEIVED); + + this._setReadyState(this.LOADING); + + this._responseText = r.content.toString(); + this._setReadyState(this.DONE); + } + + }).catch(e => { + this._errorFlag = true; + this._setReadyState(this.DONE); + }); + } + } + + public setRequestHeader(header: string, value: string) { + if (types.isDefined(this._options) && types.isString(header) && types.isString(value)) { + this._options.headers[header] = value; + } + } + + public getAllResponseHeaders(): string { + if (this._readyState < 2 || this._errorFlag) { + return ""; + } + + var result = ""; + + for (var i in this._headers) { + // Cookie headers are excluded + if (i !== "set-cookie" && i !== "set-cookie2") { + result += i + ": " + this._headers[i] + "\r\n"; + } + } + return result.substr(0, result.length - 2); + } + + public getResponseHeader(header: string): string { + if (types.isString(header) && this._readyState > 1 + && this._headers + && this._headers[header] + && !this._errorFlag + ) { + return this._headers[header]; + } + + return null; + } + + public overrideMimeType(mime: string) { + // + } + + get readyState(): number { + return this._readyState; + } + + public get responseType(): string { + return this._responseType; + } + + public set responseType(value: string) { + if (value === "" || value === "text") { + this._responseType = value; + } else { + throw new Error(`Response type of '${value}' not supported.`); + } + } + + private _setReadyState(value: number) { + if (this._readyState !== value) { + this._readyState = value; + + if (types.isFunction(this.onreadystatechange)) { + this.onreadystatechange(); + } + } + + if (this._readyState === this.DONE) { + if (this._errorFlag && types.isFunction(this.onerror)) { + this.onerror(); + } + if (!this._errorFlag && types.isFunction(this.onload)) { + this.onload(); + } + } + } + + get responseText(): string { + return this._responseText; + } + + get response(): any { + return this._response; + } + + get status(): number { + return this._status; + } + + get statusText(): string { + if (this._readyState === this.UNSENT || this._readyState === this.OPENED || this._errorFlag) { + return ""; + } + return this._status + " " + statuses[this._status]; + } +} + +var statuses = { + 100: "Continue", + 101: "Switching Protocols", + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non - Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 307: "Temporary Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Request Entity Too Large", + 414: "Request - URI Too Long", + 415: "Unsupported Media Type", + 416: "Requested Range Not Satisfiable", + 417: "Expectation Failed", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported" +}; From 54c0de8df629a024db973ba579098f3bc1f4f8b3 Mon Sep 17 00:00:00 2001 From: Vladimir Enchev Date: Mon, 20 Jul 2015 10:58:29 +0300 Subject: [PATCH 2/5] XMLHttpRequest separated from http --- CrossPlatformModules.csproj | 6 ++- apps/tests/http-tests.ts | 85 ++++++++++++++++++------------------- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj index a0a81df7a..c6fd5807f 100644 --- a/CrossPlatformModules.csproj +++ b/CrossPlatformModules.csproj @@ -1734,7 +1734,9 @@ - + + + @@ -1785,7 +1787,7 @@ False - + \ No newline at end of file diff --git a/apps/tests/http-tests.ts b/apps/tests/http-tests.ts index 15e125b7d..714558308 100644 --- a/apps/tests/http-tests.ts +++ b/apps/tests/http-tests.ts @@ -333,15 +333,15 @@ export var test_request_headersSentAndReceivedProperly = function (done) { method: "GET", headers: { "Content-Type": "application/json" } }).then(function (response) { - result = response.headers; - try { - TKUnit.assert(result["Content-Type"] === "application/json", "Headers not sent/received properly!"); - done(null); - } - catch (err) { - done(err); - } - }, function (e) { + result = response.headers; + try { + TKUnit.assert(result["Content-Type"] === "application/json", "Headers not sent/received properly!"); + done(null); + } + catch (err) { + done(err); + } + }, function (e) { done(e); }); }; @@ -355,15 +355,15 @@ export var test_request_contentSentAndReceivedProperly = function (done) { headers: { "Content-Type": "application/x-www-form-urlencoded" }, content: "MyVariableOne=ValueOne&MyVariableTwo=ValueTwo" }).then(function (response) { - result = response.content.toJSON(); - try { - TKUnit.assert(result["form"]["MyVariableOne"] === "ValueOne" && result["form"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!"); - done(null); - } - catch (err) { - done(err); - } - }, function (e) { + result = response.content.toJSON(); + try { + TKUnit.assert(result["form"]["MyVariableOne"] === "ValueOne" && result["form"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!"); + done(null); + } + catch (err) { + done(err); + } + }, function (e) { done(e); }); }; @@ -379,15 +379,15 @@ export var test_request_NonStringHeadersSentAndReceivedProperly = function (done headers: { "Content-Type": "application/x-www-form-urlencoded", "Content-Length": postData.length }, content: postData }).then(function (response) { - result = response.content.toJSON(); - try { - TKUnit.assert(result["form"]["MyVariableOne"] === "ValueOne" && result["form"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!"); - done(null); - } - catch (err) { - done(err); - } - }, function (e) { + result = response.content.toJSON(); + try { + TKUnit.assert(result["form"]["MyVariableOne"] === "ValueOne" && result["form"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!"); + done(null); + } + catch (err) { + done(err); + } + }, function (e) { done(e); }); }; @@ -404,24 +404,23 @@ export var test_request_jsonAsContentSentAndReceivedProperly = function (done) { headers: { "Content-Type": "application/json" }, content: JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" }) }).then(function (response) { - // result = response.content.toJSON(); - // - result = response.content.toJSON(); - try - { - TKUnit.assert(result["json"]["MyVariableOne"] === "ValueOne" && result["json"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!"); - done(null); - } - catch (err) { - done(err); - } + // result = response.content.toJSON(); + // + result = response.content.toJSON(); + try { + TKUnit.assert(result["json"]["MyVariableOne"] === "ValueOne" && result["json"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!"); + done(null); + } + catch (err) { + done(err); + } // // console.log(result); - }, function (e) { - // + }, function (e) { + // done(e); - // - // console.log("Error occurred " + e); + // + // console.log("Error occurred " + e); }); // ``` // @@ -452,4 +451,4 @@ function doRequest(url: string, done: Function) { }, function (e) { done(e); }); -} \ No newline at end of file +}; \ No newline at end of file From e2f464e1d2e64563c41c9697570f6def25b42b5a Mon Sep 17 00:00:00 2001 From: Vladimir Enchev Date: Mon, 20 Jul 2015 14:42:29 +0300 Subject: [PATCH 3/5] FormData support added --- apps/tests/fetch-tests.ts | 14 +++++++---- apps/tests/http-tests.ts | 26 +++++++++++++++++++ apps/tests/xhr-tests.ts | 29 +++++++++++++++++++-- fetch/fetch.d.ts | 2 +- fetch/fetch.js | 4 +-- globals/globals.ts | 1 + http/http-request.android.ts | 4 +-- http/http-request.ios.ts | 4 +-- http/http.d.ts | 2 +- xhr/xhr.ts | 49 ++++++++++++++++++++++++++++++++---- 10 files changed, 115 insertions(+), 20 deletions(-) diff --git a/apps/tests/fetch-tests.ts b/apps/tests/fetch-tests.ts index 2553995db..6d71a4bf5 100644 --- a/apps/tests/fetch-tests.ts +++ b/apps/tests/fetch-tests.ts @@ -123,6 +123,7 @@ export var test_fetch_arrayBuffer = function (done: (err: Error, res?: string) = // ``` // }; +*/ export var test_fetch_formData = function (done: (err: Error, res?: string) => void) { var result; @@ -145,7 +146,7 @@ export var test_fetch_formData = function (done: (err: Error, res?: string) => v // ``` // }; -*/ + export var test_fetch_fail_invalid_url = function (done) { var completed: boolean; var isReady = function () { return completed; } @@ -231,16 +232,19 @@ export var test_fetch_headers_sent = function (done) { }; export var test_fetch_post_form_data = function (done) { + var data = new FormData(); + data.append("MyVariableOne", "ValueOne"); + data.append("MyVariableTwo", "ValueTwo"); + fetchModule.fetch("https://httpbin.org/post", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: "MyVariableOne=ValueOne&MyVariableTwo=ValueTwo" + body: data }).then(r => { - // return r.formData(); Uncomment this when FormData is available! - return r.json(); + return r.formData(); }).then(function (r) { try { - TKUnit.assert(r.form["MyVariableOne"] === "ValueOne" && r.form["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly! Actual result is: " + r.form); + TKUnit.assert(r instanceof FormData, "Content not sent/received properly! Actual result is: " + r); done(null); } catch (err) { diff --git a/apps/tests/http-tests.ts b/apps/tests/http-tests.ts index 714558308..a3c7b49a7 100644 --- a/apps/tests/http-tests.ts +++ b/apps/tests/http-tests.ts @@ -368,6 +368,32 @@ export var test_request_contentSentAndReceivedProperly = function (done) { }); }; +export var test_request_FormDataContentSentAndReceivedProperly = function (done) { + var result; + + var data = new FormData(); + data.append("MyVariableOne", "ValueOne"); + data.append("MyVariableTwo", "ValueTwo"); + + http.request({ + url: "https://httpbin.org/post", + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + content: data + }).then(function (response) { + result = response.content.toJSON(); + try { + TKUnit.assert(result["form"]["MyVariableOne"] === "ValueOne" && result["form"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly!"); + done(null); + } + catch (err) { + done(err); + } + }, function (e) { + done(e); + }); +}; + export var test_request_NonStringHeadersSentAndReceivedProperly = function (done) { var result; diff --git a/apps/tests/xhr-tests.ts b/apps/tests/xhr-tests.ts index 3836be4a3..f10f8075a 100644 --- a/apps/tests/xhr-tests.ts +++ b/apps/tests/xhr-tests.ts @@ -113,6 +113,30 @@ export var test_XMLHttpRequest_contentSentAndReceivedProperly = function (done) xhr.send(JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" })); }; +export var test_XMLHttpRequest_FormDataContentSentAndReceivedProperly = function (done) { + xhr = new XMLHttpRequest(); + xhr.open("POST", "https://httpbin.org/post"); + xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + xhr.onreadystatechange = function () { + if (xhr.readyState > 3) { + var result = JSON.parse(xhr.responseText); + try { + TKUnit.assert(result["form"]["MyVariableOne"] === "ValueOne" && result["form"]["MyVariableTwo"] === "ValueTwo", "Content not sent/received properly! Result is: " + xhr.responseText); + done(null); + } + catch (err) { + done(err); + } + } + }; + + var data = new FormData(); + data.append("MyVariableOne", "ValueOne"); + data.append("MyVariableTwo", "ValueTwo"); + + xhr.send(data); +}; + export var test_XMLHttpRequest_abortShouldCancelonreadystatechange = function (done) { var flag = false; @@ -173,11 +197,12 @@ export function test_responseType(done) { let xhr = new XMLHttpRequest(); xhr.responseType = ""; xhr.responseType = "text"; + xhr.responseType = "json"; TKUnit.assertThrows( - () => xhr.responseType = "json", + () => xhr.responseType = "arraybuffer", "Didn't raise on unsupported type.", - "Response type of 'json' not supported." + "Response type of 'arraybuffer' not supported." ); done(null); } diff --git a/fetch/fetch.d.ts b/fetch/fetch.d.ts index 67745571e..d67dd5ecd 100644 --- a/fetch/fetch.d.ts +++ b/fetch/fetch.d.ts @@ -54,8 +54,8 @@ declare module "fetch" { /* arrayBuffer(): Promise; blob(): Promise; - formData(): Promise; */ + formData(): Promise; json(): Promise; text(): Promise; } diff --git a/fetch/fetch.js b/fetch/fetch.js index 3b0ec8ce1..188f17d78 100644 --- a/fetch/fetch.js +++ b/fetch/fetch.js @@ -110,7 +110,7 @@ } var support = { - blob: 'FileReader' in self && 'Blob' in self && (function () { + blob: 'FileReader' in global && 'Blob' in global && (function () { try { new Blob(); return true @@ -118,7 +118,7 @@ return false } })(), - formData: 'FormData' in self + formData: 'FormData' in global } function Body() { diff --git a/globals/globals.ts b/globals/globals.ts index 86d704e85..66e682b20 100644 --- a/globals/globals.ts +++ b/globals/globals.ts @@ -15,6 +15,7 @@ if (types.isUndefined(global.NSObject)) { } global.XMLHttpRequest = xhr.XMLHttpRequest; +global.FormData = xhr.FormData; global.alert = dialogs.alert; export function Deprecated(target: Object, key?: string | symbol, descriptor?: any) { diff --git a/http/http-request.android.ts b/http/http-request.android.ts index 732255c6c..192cb422f 100644 --- a/http/http-request.android.ts +++ b/http/http-request.android.ts @@ -73,8 +73,8 @@ function buildJavaOptions(options: http.HttpRequestOptions) { if (types.isString(options.method)) { javaOptions.method = options.method; } - if (options.content) { - javaOptions.content = options.content; + if (types.isString(options.content) || options.content instanceof FormData) { + javaOptions.content = options.content.toString(); } if (types.isNumber(options.timeout)) { javaOptions.timeout = options.timeout; diff --git a/http/http-request.ios.ts b/http/http-request.ios.ts index 73af2e074..38d2e49f6 100644 --- a/http/http-request.ios.ts +++ b/http/http-request.ios.ts @@ -32,8 +32,8 @@ export function request(options: http.HttpRequestOptions): Promisedata).toString(); } http.request(this._options).then(r=> { @@ -80,7 +88,12 @@ export class XMLHttpRequest { this._setReadyState(this.LOADING); - this._responseText = r.content.toString(); + if (this.responseType === XMLHttpRequestResponseType.empty || + this.responseType === XMLHttpRequestResponseType.text || + this.responseType === XMLHttpRequestResponseType.json) { + this._responseText = r.content.toString; + } + this._setReadyState(this.DONE); } @@ -138,7 +151,7 @@ export class XMLHttpRequest { } public set responseType(value: string) { - if (value === "" || value === "text") { + if (value === XMLHttpRequestResponseType.empty || value in XMLHttpRequestResponseType) { this._responseType = value; } else { throw new Error(`Response type of '${value}' not supported.`); @@ -165,7 +178,11 @@ export class XMLHttpRequest { } get responseText(): string { - return this._responseText; + if (types.isFunction(this._responseText)) { + return this._responseText(); + } + + return ""; } get response(): any { @@ -226,3 +243,25 @@ var statuses = { 504: "Gateway Timeout", 505: "HTTP Version Not Supported" }; + +export class FormData { + private _data: Map; + + constructor() { + this._data = new Map(); + } + + append(name: string, value: any) { + this._data.set(name, value); + } + + toString(): string { + var arr = new Array(); + + this._data.forEach(function (value, name, map) { + arr.push(`${encodeURIComponent(name) }=${encodeURIComponent(value) }`); + }); + + return arr.join("&"); + } +} \ No newline at end of file From 272597f7bdb31eb9928593f7c80c84318dc09a46 Mon Sep 17 00:00:00 2001 From: Vladimir Enchev Date: Mon, 20 Jul 2015 14:52:04 +0300 Subject: [PATCH 4/5] global XMLHttpRequest declaration extended --- apps/tests/xhr-tests.ts | 2 +- declarations.d.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/tests/xhr-tests.ts b/apps/tests/xhr-tests.ts index f10f8075a..912a2e0e4 100644 --- a/apps/tests/xhr-tests.ts +++ b/apps/tests/xhr-tests.ts @@ -134,7 +134,7 @@ export var test_XMLHttpRequest_FormDataContentSentAndReceivedProperly = function data.append("MyVariableOne", "ValueOne"); data.append("MyVariableTwo", "ValueTwo"); - xhr.send(data); + xhr.send(data); }; export var test_XMLHttpRequest_abortShouldCancelonreadystatechange = function (done) { diff --git a/declarations.d.ts b/declarations.d.ts index 91eb4ca7d..1bb97cf9f 100644 --- a/declarations.d.ts +++ b/declarations.d.ts @@ -1,4 +1,8 @@ /* tslint:disable:no-unused-variable */ +interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { + send(data?: FormData): void; +} + interface Console { time(reportName: string): void; timeEnd(reportName: string): void; From 78781b971d1a8b358f8db7f4097a946347d8a1e3 Mon Sep 17 00:00:00 2001 From: Vladimir Enchev Date: Mon, 20 Jul 2015 15:51:43 +0300 Subject: [PATCH 5/5] fetch exposed in global context --- CrossPlatformModules.csproj | 7 +-- apps/tests/fetch-tests.ts | 31 +++++++------ declarations.d.ts | 82 ++++++++++++++++++++++++++++++++- fetch/fetch.d.ts | 90 ------------------------------------- globals/globals.ts | 3 ++ 5 files changed, 101 insertions(+), 112 deletions(-) delete mode 100644 fetch/fetch.d.ts diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj index c6fd5807f..7f9a72e2b 100644 --- a/CrossPlatformModules.csproj +++ b/CrossPlatformModules.csproj @@ -300,7 +300,6 @@ - file-name-resolver.d.ts @@ -1734,9 +1733,7 @@ - - - + @@ -1787,7 +1784,7 @@ False - + \ No newline at end of file diff --git a/apps/tests/fetch-tests.ts b/apps/tests/fetch-tests.ts index 6d71a4bf5..de541975a 100644 --- a/apps/tests/fetch-tests.ts +++ b/apps/tests/fetch-tests.ts @@ -1,6 +1,5 @@ /* tslint:disable:no-unused-variable */ import TKUnit = require("./TKUnit"); -import fetchModule = require("fetch"); import types = require("utils/types"); // @@ -12,7 +11,7 @@ import types = require("utils/types"); // export var test_fetch_defined = function () { - TKUnit.assert(types.isDefined((fetchModule.fetch)), "Method fetch() should be defined!"); + TKUnit.assert(types.isDefined((fetch)), "Method fetch() should be defined!"); }; export var test_fetch = function (done: (err: Error, res?: string) => void) { @@ -20,10 +19,10 @@ export var test_fetch = function (done: (err: Error, res?: string) => void) { // // ### Get Response from URL // ``` JavaScript - fetchModule.fetch("https://httpbin.org/get").then(function (r) { + fetch("https://httpbin.org/get").then(function (r) { //// Argument (r) is Response! // - TKUnit.assert(r instanceof fetchModule.Response, "Result from fetch() should be valid Response object! Actual result is: " + result); + TKUnit.assert(r instanceof Response, "Result from fetch() should be valid Response object! Actual result is: " + result); done(null); // }, function (e) { @@ -42,7 +41,7 @@ export var test_fetch_text = function (done: (err: Error, res?: string) => void) // // ### Get string from URL // ``` JavaScript - fetchModule.fetch("https://httpbin.org/get").then(response => { return response.text(); }).then(function (r) { + fetch("https://httpbin.org/get").then(response => { return response.text(); }).then(function (r) { //// Argument (r) is string! // TKUnit.assert(types.isString(r), "Result from text() should be string! Actual result is: " + r); @@ -64,7 +63,7 @@ export var test_fetch_json = function (done: (err: Error, res?: string) => void) // // ### Get JSON from URL // ``` JavaScript - fetchModule.fetch("https://httpbin.org/get").then(response => { return response.json(); }).then(function (r) { + fetch("https://httpbin.org/get").then(response => { return response.json(); }).then(function (r) { //// Argument (r) is JSON object! // TKUnit.assert(types.isString(JSON.stringify(r)), "Result from json() should be JSON object! Actual result is: " + r); @@ -86,7 +85,7 @@ export var test_fetch_blob = function (done: (err: Error, res?: string) => void) // // ### Get Blob from URL // ``` JavaScript - fetchModule.fetch("https://httpbin.org/get").then(response => { return response.blob(); }).then(function (r) { + fetch("https://httpbin.org/get").then(response => { return response.blob(); }).then(function (r) { //// Argument (r) is Blob object! // TKUnit.assert(r instanceof Blob, "Result from blob() should be Blob object! Actual result is: " + r); @@ -108,7 +107,7 @@ export var test_fetch_arrayBuffer = function (done: (err: Error, res?: string) = // // ### Get ArrayBuffer from URL // ``` JavaScript - fetchModule.fetch("https://httpbin.org/get").then(response => { return response.arrayBuffer(); }).then(function (r) { + fetch("https://httpbin.org/get").then(response => { return response.arrayBuffer(); }).then(function (r) { //// Argument (r) is ArrayBuffer object! // TKUnit.assert(r instanceof ArrayBuffer, "Result from arrayBuffer() should be ArrayBuffer object! Actual result is: " + r); @@ -131,7 +130,7 @@ export var test_fetch_formData = function (done: (err: Error, res?: string) => v // // ### Get FormData from URL // ``` JavaScript - fetchModule.fetch("https://httpbin.org/get").then(response => { return response.formData(); }).then(function (r) { + fetch("https://httpbin.org/get").then(response => { return response.formData(); }).then(function (r) { //// Argument (r) is FormData object! // TKUnit.assert(r instanceof FormData, "Result from formData() should be FormData object! Actual result is: " + r); @@ -151,7 +150,7 @@ export var test_fetch_fail_invalid_url = function (done) { var completed: boolean; var isReady = function () { return completed; } - fetchModule.fetch("hgfttp://httpbin.org/get").catch(function (e) { + fetch("hgfttp://httpbin.org/get").catch(function (e) { completed = true; done(null) }); @@ -162,7 +161,7 @@ export var test_fetch_response_status = function (done) { // // ### Get Response status // ``` fetch - fetchModule.fetch("https://httpbin.org/get").then(function (response) { + fetch("https://httpbin.org/get").then(function (response) { //// Argument (response) is Response! var statusCode = response.status; // @@ -189,7 +188,7 @@ export var test_fetch_response_headers = function (done) { // // ### Get response headers // ``` JavaScript - fetchModule.fetch("https://httpbin.org/get").then(function (response) { + fetch("https://httpbin.org/get").then(function (response) { //// Argument (response) is Response! // var all = response.headers.getAll(); // @@ -212,9 +211,9 @@ export var test_fetch_response_headers = function (done) { }; export var test_fetch_headers_sent = function (done) { - var result: fetchModule.Headers; + var result: Headers; - fetchModule.fetch("https://httpbin.org/get", { + fetch("https://httpbin.org/get", { method: "GET", headers: { "Content-Type": "application/json" } }).then(function (response) { @@ -236,7 +235,7 @@ export var test_fetch_post_form_data = function (done) { data.append("MyVariableOne", "ValueOne"); data.append("MyVariableTwo", "ValueTwo"); - fetchModule.fetch("https://httpbin.org/post", { + fetch("https://httpbin.org/post", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: data @@ -259,7 +258,7 @@ export var test_fetch_post_json = function (done) { // // ### Post JSON // ``` JavaScript - fetchModule.fetch("https://httpbin.org/post", { + fetch("https://httpbin.org/post", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" }) diff --git a/declarations.d.ts b/declarations.d.ts index 1bb97cf9f..61295bc03 100644 --- a/declarations.d.ts +++ b/declarations.d.ts @@ -1,5 +1,85 @@ /* tslint:disable:no-unused-variable */ -interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { +declare class Request { + constructor(input: string|Request, init?: RequestInit); + method: string; + url: string; + headers: Headers; + context: RequestContext; + referrer: string; + mode: RequestMode; + credentials: RequestCredentials; + cache: RequestCache; +} + +interface RequestInit { + method?: string; + headers?: HeaderInit|{ [index: string]: string }; + body?: BodyInit; + mode?: RequestMode; + credentials?: RequestCredentials; + cache?: RequestCache; +} + +declare enum RequestContext { + "audio", "beacon", "cspreport", "download", "embed", "eventsource", "favicon", "fetch", + "font", "form", "frame", "hyperlink", "iframe", "image", "imageset", "import", + "internal", "location", "manifest", "object", "ping", "plugin", "prefetch", "script", + "serviceworker", "sharedworker", "subresource", "style", "track", "video", "worker", + "xmlhttprequest", "xslt" +} + +declare enum RequestMode { "same-origin", "no-cors", "cors" } +declare enum RequestCredentials { "omit", "same-origin", "include" } +declare enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" } + +declare class Headers { + append(name: string, value: string): void; + delete(name: string): void; + get(name: string): string; + getAll(name: string): Array; + has(name: string): boolean; + set(name: string, value: string): void; +} + +declare class Body { + bodyUsed: boolean; + /* + arrayBuffer(): Promise; + blob(): Promise; + */ + formData(): Promise; + json(): Promise; + text(): Promise; +} + +declare class Response extends Body { + constructor(body?: BodyInit, init?: ResponseInit); + error(): Response; + redirect(url: string, status: number): Response; + type: ResponseType; + url: string; + status: number; + ok: boolean; + statusText: string; + headers: Headers; + clone(): Response; +} + +declare enum ResponseType { "basic", "cors", "default", "error", "opaque" } + +declare class ResponseInit { + status: number; + statusText: string; + headers: HeaderInit; +} + +declare type HeaderInit = Headers|Array; +declare type BodyInit = Blob|FormData|string; +declare type RequestInfo = Request|string; + +declare function fetch(url: string, init?: RequestInit): Promise; + +interface XMLHttpRequest { send(data?: FormData): void; } diff --git a/fetch/fetch.d.ts b/fetch/fetch.d.ts deleted file mode 100644 index d67dd5ecd..000000000 --- a/fetch/fetch.d.ts +++ /dev/null @@ -1,90 +0,0 @@ -// Type definitions for fetch API -// Project: https://github.com/github/fetch -// Definitions by: Ryan Graham -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/// - -declare module "fetch" { - - class Request { - constructor(input: string|Request, init?: RequestInit); - method: string; - url: string; - headers: Headers; - context: RequestContext; - referrer: string; - mode: RequestMode; - credentials: RequestCredentials; - cache: RequestCache; - } - - interface RequestInit { - method?: string; - headers?: HeaderInit|{ [index: string]: string }; - body?: BodyInit; - mode?: RequestMode; - credentials?: RequestCredentials; - cache?: RequestCache; - } - - enum RequestContext { - "audio", "beacon", "cspreport", "download", "embed", "eventsource", "favicon", "fetch", - "font", "form", "frame", "hyperlink", "iframe", "image", "imageset", "import", - "internal", "location", "manifest", "object", "ping", "plugin", "prefetch", "script", - "serviceworker", "sharedworker", "subresource", "style", "track", "video", "worker", - "xmlhttprequest", "xslt" - } - - enum RequestMode { "same-origin", "no-cors", "cors" } - enum RequestCredentials { "omit", "same-origin", "include" } - enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" } - - class Headers { - append(name: string, value: string): void; - delete(name: string): void; - get(name: string): string; - getAll(name: string): Array; - has(name: string): boolean; - set(name: string, value: string): void; - } - - class Body { - bodyUsed: boolean; -/* - arrayBuffer(): Promise; - blob(): Promise; -*/ - formData(): Promise; - json(): Promise; - text(): Promise; - } - - class Response extends Body { - constructor(body?: BodyInit, init?: ResponseInit); - error(): Response; - redirect(url: string, status: number): Response; - type: ResponseType; - url: string; - status: number; - ok: boolean; - statusText: string; - headers: Headers; - clone(): Response; - } - - enum ResponseType { "basic", "cors", "default", "error", "opaque" } - - class ResponseInit { - status: number; - statusText: string; - headers: HeaderInit; - } - - type HeaderInit = Headers|Array; - type BodyInit = Blob|FormData|string; - type RequestInfo = Request|string; - - /* tslint:disable */ - function fetch(url: string, init?: RequestInit): Promise; -} \ No newline at end of file diff --git a/globals/globals.ts b/globals/globals.ts index 66e682b20..c7b69747a 100644 --- a/globals/globals.ts +++ b/globals/globals.ts @@ -18,6 +18,9 @@ global.XMLHttpRequest = xhr.XMLHttpRequest; global.FormData = xhr.FormData; global.alert = dialogs.alert; +var fetchModule = require("fetch"); +require("utils/module-merge").merge(fetchModule, global); + export function Deprecated(target: Object, key?: string | symbol, descriptor?: any) { if (descriptor) { var originalMethod = descriptor.value;