Add ability to specify a transport to avoid autodetection, 0.7.0

This commit is contained in:
Kegan Myers 2014-04-16 10:40:03 -05:00
parent 5e7f079b43
commit fb91130952
15 changed files with 232 additions and 125 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "Typertext", "name": "Typertext",
"version": "0.6.1", "version": "0.7.0",
"homepage": "https://github.com/terribleplan/Typertext", "homepage": "https://github.com/terribleplan/Typertext",
"authors": [ "authors": [
"Kegan Myers <kegan@keganmyers.com>" "Kegan Myers <kegan@keganmyers.com>"

36
build/typertext.d.ts vendored
View File

@ -9,11 +9,16 @@ declare module Typertext {
public GetCustom(): T; public GetCustom(): T;
} }
} }
declare module Typertext.Transport {
interface TransportConstructor {
new(method: Http.HttpMethod, request: Http.HttpUrl, postData?: Http.HttpPostData, callback?: Http.HttpResponseHandler): GenericTransport;
}
}
declare module Typertext { declare module Typertext {
interface GenericRequest<T extends GenericResponseHandler<GenericResponse<any>>> { interface GenericRequest<T extends GenericResponseHandler<GenericResponse<any>>> {
Get(request: Http.HttpUrl, callback: T): void; Get(request: Http.HttpUrl, callback: T): void;
Post(request: Http.HttpUrl, postData: Http.HttpPostData, callback: T): void; Post(request: Http.HttpUrl, postData: Http.HttpPostData, callback: T): void;
RawRequest(method: Http.HttpMethod, request: Http.HttpUrl, postData?: Http.HttpPostData, callback?: T): void; RawRequest(method: Http.HttpMethod, request: Http.HttpUrl, postData?: Http.HttpPostData, callback?: T, transport?: Transport.TransportConstructor): void;
} }
} }
declare module Typertext { declare module Typertext {
@ -66,7 +71,7 @@ declare module Typertext.Http {
constructor(); constructor();
public Get(request: HttpUrl, callback: HttpResponseHandler): void; public Get(request: HttpUrl, callback: HttpResponseHandler): void;
public Post(request: HttpUrl, postData: HttpPostData, callback: HttpResponseHandler): void; public Post(request: HttpUrl, postData: HttpPostData, callback: HttpResponseHandler): void;
public RawRequest(method: HttpMethod, request: HttpUrl, postData?: HttpPostData, callback?: HttpResponseHandler): void; public RawRequest(method: HttpMethod, request: HttpUrl, postData?: HttpPostData, callback?: HttpResponseHandler, transport?: Transport.TransportConstructor): void;
} }
} }
declare module Typertext.Http { declare module Typertext.Http {
@ -127,7 +132,7 @@ declare module Typertext.Json {
constructor(jsonContentType?: string); constructor(jsonContentType?: string);
public Get(request: Http.HttpUrl, callback: JsonResponseHandler): void; public Get(request: Http.HttpUrl, callback: JsonResponseHandler): void;
public Post(request: Http.HttpUrl, postData: Http.HttpPostData, callback: JsonResponseHandler): void; public Post(request: Http.HttpUrl, postData: Http.HttpPostData, callback: JsonResponseHandler): void;
public RawRequest(method: Http.HttpMethod, request: Http.HttpUrl, postData?: Http.HttpPostData, callback?: JsonResponseHandler): void; public RawRequest(method: Http.HttpMethod, request: Http.HttpUrl, postData?: Http.HttpPostData, callback?: JsonResponseHandler, transport?: Transport.TransportConstructor): void;
} }
} }
declare module Typertext.Json { declare module Typertext.Json {
@ -144,22 +149,37 @@ declare module Typertext.Json {
} }
} }
declare module Typertext.Transport { declare module Typertext.Transport {
class GenericTransport { interface GenericTransport {
constructor(method: Http.HttpMethod, request: Http.HttpUrl, postData: Http.HttpPostData, callback: Http.HttpResponseHandler); Send(): void;
Destroy(): void;
} }
} }
declare module Typertext.Transport { declare module Typertext.Transport {
class TransportChooser { class TransportChooser {
static Transport(method: Http.HttpMethod, request: Http.HttpUrl, postData: Http.HttpPostData, callback: Http.HttpResponseHandler): GenericTransport; static Transport(method: Http.HttpMethod, request: Http.HttpUrl, postData: Http.HttpPostData, callback: Http.HttpResponseHandler): TransportConstructor;
} }
} }
declare module Typertext.Transport { declare module Typertext.Transport {
class XDR extends GenericTransport { class XDR implements GenericTransport {
private xdr;
private postData;
private method;
private request;
private callback;
constructor(method: Http.HttpMethod, request: Http.HttpUrl, postData?: Http.HttpPostData, callback?: Http.HttpResponseHandler); constructor(method: Http.HttpMethod, request: Http.HttpUrl, postData?: Http.HttpPostData, callback?: Http.HttpResponseHandler);
public Send(): void;
public Destroy(): void;
} }
} }
declare module Typertext.Transport { declare module Typertext.Transport {
class XHR extends GenericTransport { class XHR implements GenericTransport {
private xhr;
private postData;
private method;
private request;
private callback;
constructor(method: Http.HttpMethod, request: Http.HttpUrl, postData?: Http.HttpPostData, callback?: Http.HttpResponseHandler); constructor(method: Http.HttpMethod, request: Http.HttpUrl, postData?: Http.HttpPostData, callback?: Http.HttpResponseHandler);
public Send(): void;
public Destroy(): void;
} }
} }

View File

@ -22,6 +22,12 @@ var Typertext;
Typertext.BaseException = BaseException; Typertext.BaseException = BaseException;
})(Typertext || (Typertext = {})); })(Typertext || (Typertext = {}));
var Typertext; var Typertext;
(function (Typertext) {
(function (Transport) {
})(Typertext.Transport || (Typertext.Transport = {}));
var Transport = Typertext.Transport;
})(Typertext || (Typertext = {}));
var Typertext;
(function (Typertext) { (function (Typertext) {
})(Typertext || (Typertext = {})); })(Typertext || (Typertext = {}));
@ -102,6 +108,8 @@ var Typertext;
var Typertext; var Typertext;
(function (Typertext) { (function (Typertext) {
(function (Http) { (function (Http) {
var TransportChooser = Typertext.Transport.TransportChooser;
var HttpRequest = (function () { var HttpRequest = (function () {
function HttpRequest() { function HttpRequest() {
} }
@ -113,11 +121,18 @@ var Typertext;
this.RawRequest(1 /* POST */, request, postData, callback); this.RawRequest(1 /* POST */, request, postData, callback);
}; };
HttpRequest.prototype.RawRequest = function (method, request, postData, callback) { HttpRequest.prototype.RawRequest = function (method, request, postData, callback, transport) {
if (typeof postData === "undefined") { postData = {}; } if (typeof postData === "undefined") { postData = {}; }
if (typeof callback === "undefined") { callback = function (c) { if (!callback)
}; } callback = function (c) {
Typertext.Transport.TransportChooser.Transport(method, request, postData, callback); return null;
};
if (!transport)
transport = TransportChooser.Transport(method, request, postData, callback);
var transportInstance = new transport(method, request, postData, callback);
transportInstance.Send();
}; };
return HttpRequest; return HttpRequest;
})(); })();
@ -310,7 +325,7 @@ var Typertext;
this.RawRequest(1 /* POST */, request, postData, callback); this.RawRequest(1 /* POST */, request, postData, callback);
}; };
JsonRequest.prototype.RawRequest = function (method, request, postData, callback) { JsonRequest.prototype.RawRequest = function (method, request, postData, callback, transport) {
var _this = this; var _this = this;
if (typeof postData === "undefined") { postData = {}; } if (typeof postData === "undefined") { postData = {}; }
if (typeof callback != "function") { if (typeof callback != "function") {
@ -326,7 +341,7 @@ var Typertext;
} }
callback(Typertext.Json.JsonResponse.fromHttpResponse(response)); callback(Typertext.Json.JsonResponse.fromHttpResponse(response));
}); }, transport);
}; };
return JsonRequest; return JsonRequest;
})(); })();
@ -368,18 +383,6 @@ var Typertext;
var Json = Typertext.Json; var Json = Typertext.Json;
})(Typertext || (Typertext = {})); })(Typertext || (Typertext = {}));
var Typertext; var Typertext;
(function (Typertext) {
(function (Transport) {
var GenericTransport = (function () {
function GenericTransport(method, request, postData, callback) {
}
return GenericTransport;
})();
Transport.GenericTransport = GenericTransport;
})(Typertext.Transport || (Typertext.Transport = {}));
var Transport = Typertext.Transport;
})(Typertext || (Typertext = {}));
var Typertext;
(function (Typertext) { (function (Typertext) {
(function (Transport) { (function (Transport) {
var HttpUrl = Typertext.Http.HttpUrl; var HttpUrl = Typertext.Http.HttpUrl;
@ -400,11 +403,11 @@ var Typertext;
var origin = HttpUrl.FromUrl(window.location.href); var origin = HttpUrl.FromUrl(window.location.href);
if (!origin.CrossOriginCheck(origin) || !ieLte9) { if (!origin.CrossOriginCheck(origin) || !ieLte9) {
return new Typertext.Transport.XHR(method, request, postData, callback); return Typertext.Transport.XHR;
} }
if (origin.GetProtocol() === request.GetProtocol()) { if (origin.GetProtocol() === request.GetProtocol()) {
return new Typertext.Transport.XDR(method, request, postData, callback); return Typertext.Transport.XDR;
} }
throw {}; throw {};
@ -424,53 +427,62 @@ var Typertext;
var HttpResponseStatus = Typertext.Http.HttpResponseStatus; var HttpResponseStatus = Typertext.Http.HttpResponseStatus;
var HttpResponse = Typertext.Http.HttpResponse; var HttpResponse = Typertext.Http.HttpResponse;
var XDR = (function (_super) { var XDR = (function () {
__extends(XDR, _super);
function XDR(method, request, postData, callback) { function XDR(method, request, postData, callback) {
if (typeof postData === "undefined") { postData = {}; } if (typeof postData === "undefined") { postData = {}; }
if (typeof callback === "undefined") { callback = function (c) { if (typeof callback === "undefined") { callback = function (c) {
return null; return null;
}; } }; }
_super.call(this, method, request, postData, callback); this.postData = postData;
this.method = method;
var xdr = new XDomainRequest(); this.request = request;
this.callback = callback;
this.xdr = new XDomainRequest();
}
XDR.prototype.Send = function () {
var _this = this;
var getHeader = function (name) { var getHeader = function (name) {
if (name.toLowerCase() === "content-type") { if (name.toLowerCase() === "content-type") {
return xdr.contentType; return _this.xdr.contentType;
} }
return undefined; return undefined;
}; };
xdr.ontimeout = function () { this.xdr.ontimeout = function () {
callback(new HttpResponse(5 /* timeout */, function (i) { _this.callback(new HttpResponse(5 /* timeout */, function (i) {
return ""; return "";
}, -1, "")); }, -1, ""));
}; };
xdr.onerror = function () { this.xdr.onerror = function () {
callback(new HttpResponse(4 /* unknownError */, getHeader, -1, xdr.responseText)); _this.callback(new HttpResponse(4 /* unknownError */, getHeader, -1, _this.xdr.responseText));
}; };
xdr.onload = function () { this.xdr.onload = function () {
callback(new HttpResponse(0 /* success */, getHeader, 200, xdr.responseText)); _this.callback(new HttpResponse(0 /* success */, getHeader, 200, _this.xdr.responseText));
}; };
xdr.onprogress = function () { this.xdr.onprogress = function () {
return null; return null;
}; };
xdr.open(HttpMethod[method], request.ToString()); this.xdr.open(HttpMethod[this.method], this.request.ToString());
if (method == 0 /* GET */) { if (this.method == 0 /* GET */) {
xdr.send(); this.xdr.send();
return; return;
} }
xdr.send(HttpUrl.UrlEncodeObject(postData)); this.xdr.send(HttpUrl.UrlEncodeObject(this.postData));
} };
XDR.prototype.Destroy = function () {
this.xdr.ontimeout = this.xdr.onerror = this.xdr.onload = this.xdr.onprogress = null;
this.xdr = null;
};
return XDR; return XDR;
})(Typertext.Transport.GenericTransport); })();
Transport.XDR = XDR; Transport.XDR = XDR;
})(Typertext.Transport || (Typertext.Transport = {})); })(Typertext.Transport || (Typertext.Transport = {}));
var Transport = Typertext.Transport; var Transport = Typertext.Transport;
@ -484,54 +496,63 @@ var Typertext;
var HttpResponseStatus = Typertext.Http.HttpResponseStatus; var HttpResponseStatus = Typertext.Http.HttpResponseStatus;
var HttpResponse = Typertext.Http.HttpResponse; var HttpResponse = Typertext.Http.HttpResponse;
var XHR = (function (_super) { var XHR = (function () {
__extends(XHR, _super);
function XHR(method, request, postData, callback) { function XHR(method, request, postData, callback) {
if (typeof postData === "undefined") { postData = {}; } if (typeof postData === "undefined") { postData = {}; }
if (typeof callback === "undefined") { callback = function (c) { if (typeof callback === "undefined") { callback = function (c) {
return null; return null;
}; } }; }
_super.call(this, method, request, postData, callback); var _this = this;
this.postData = postData;
this.method = method;
this.request = request;
this.callback = callback;
var xhr = new XMLHttpRequest(); this.xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () { this.xhr.onreadystatechange = function () {
if (xhr.readyState == 4) { if (_this.xhr.readyState == 4) {
var getHeader = function (name) { var getHeader = function (name) {
return xhr.getResponseHeader(name); return _this.xhr.getResponseHeader(name);
}; };
if (xhr.status == 200) { if (_this.xhr.status == 200) {
callback(new HttpResponse(0 /* success */, getHeader, xhr.status, xhr.responseText)); _this.callback(new HttpResponse(0 /* success */, getHeader, _this.xhr.status, _this.xhr.responseText));
} else if (xhr.status >= 400 && xhr.status < 500) { } else if (_this.xhr.status >= 400 && _this.xhr.status < 500) {
callback(new HttpResponse(2 /* clientError */, getHeader, xhr.status, xhr.responseText)); _this.callback(new HttpResponse(2 /* clientError */, getHeader, _this.xhr.status, _this.xhr.responseText));
} else if (xhr.status >= 500 && xhr.status < 600) { } else if (_this.xhr.status >= 500 && _this.xhr.status < 600) {
callback(new HttpResponse(1 /* serverError */, getHeader, xhr.status, xhr.responseText)); _this.callback(new HttpResponse(1 /* serverError */, getHeader, _this.xhr.status, _this.xhr.responseText));
} else { } else {
callback(new HttpResponse(4 /* unknownError */, getHeader, xhr.status, xhr.responseText)); _this.callback(new HttpResponse(4 /* unknownError */, getHeader, _this.xhr.status, _this.xhr.responseText));
} }
} }
}; };
xhr.ontimeout = function () { this.xhr.ontimeout = function () {
callback(new HttpResponse(5 /* timeout */, function (i) { _this.callback(new HttpResponse(5 /* timeout */, function (i) {
return ""; return "";
}, -1, "")); }, -1, ""));
}; };
}
XHR.prototype.Send = function () {
this.xhr.open(HttpMethod[this.method], this.request.ToString(), true);
xhr.open(HttpMethod[method], request.ToString(), true); if (this.method == 0 /* GET */) {
this.xhr.send();
if (method == 0 /* GET */) {
xhr.send();
return; return;
} }
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); this.xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(HttpUrl.UrlEncodeObject(postData)); this.xhr.send(HttpUrl.UrlEncodeObject(this.postData));
} };
XHR.prototype.Destroy = function () {
this.xhr.onreadystatechange = this.xhr.ontimeout = null;
this.xhr = null;
};
return XHR; return XHR;
})(Typertext.Transport.GenericTransport); })();
Transport.XHR = XHR; Transport.XHR = XHR;
})(Typertext.Transport || (Typertext.Transport = {})); })(Typertext.Transport || (Typertext.Transport = {}));
var Transport = Typertext.Transport; var Transport = Typertext.Transport;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,5 @@
/// <reference path="Transport/TransportConstructor.ts" />
/** /**
* @module Typertext * @module Typertext
* @submodule Http * @submodule Http
@ -7,6 +9,7 @@ module Typertext {
import HttpMethod = Typertext.Http.HttpMethod; import HttpMethod = Typertext.Http.HttpMethod;
import HttpPostData = Typertext.Http.HttpPostData; import HttpPostData = Typertext.Http.HttpPostData;
import HttpUrl = Typertext.Http.HttpUrl; import HttpUrl = Typertext.Http.HttpUrl;
import TransportConstructor = Typertext.Transport.TransportConstructor;
/** /**
* A class to simplify passing both the status and data of a completed proxy request * A class to simplify passing both the status and data of a completed proxy request
@ -45,7 +48,8 @@ module Typertext {
* @param {HttpUrl} request * @param {HttpUrl} request
* @param {HttpPostData} postData * @param {HttpPostData} postData
* @param {GenericResponseHandler} callback * @param {GenericResponseHandler} callback
* @param {GenericTransport} transport
*/ */
RawRequest(method:HttpMethod, request:HttpUrl, postData?:HttpPostData, callback?:T):void; RawRequest(method:HttpMethod, request:HttpUrl, postData?:HttpPostData, callback?:T, transport?:TransportConstructor):void;
} }
} }

View File

@ -1,3 +1,5 @@
//TODO add support for IE8-9 CORS via XDomain //TODO add support for IE8-9 CORS via XDomain
//TODO better error handling, ala exceptions //TODO better error handling, ala exceptions
@ -6,6 +8,10 @@
* @module Http * @module Http
*/ */
module Typertext.Http { module Typertext.Http {
import GenericTransport = Typertext.Transport.GenericTransport;
import TransportChooser = Typertext.Transport.TransportChooser;
import TransportConstructor = Typertext.Transport.TransportConstructor;
export class HttpRequest implements Typertext.GenericRequest<HttpResponseHandler> { export class HttpRequest implements Typertext.GenericRequest<HttpResponseHandler> {
/** /**
* The class that everything that calls an http(s) server should use and build on top of using callbacks * The class that everything that calls an http(s) server should use and build on top of using callbacks
@ -49,10 +55,18 @@ module Typertext.Http {
* @param {HttpUrl} request * @param {HttpUrl} request
* @param {HttpPostData} postData * @param {HttpPostData} postData
* @param {HttpResponseHandler} callback * @param {HttpResponseHandler} callback
* @param {GenericTransport} transport
*/ */
public RawRequest(method:HttpMethod, request:HttpUrl, postData:HttpPostData = {}, callback:HttpResponseHandler = (c)=> { public RawRequest(method:HttpMethod, request:HttpUrl, postData:HttpPostData = {}, callback?:HttpResponseHandler, transport?:TransportConstructor):void {
}):void { if (!callback)
Typertext.Transport.TransportChooser.Transport(method, request, postData, callback); callback = (c)=> null;
if (!transport)
transport = TransportChooser.Transport(method, request, postData, callback);
//This is guaranteed to return a GenericTransport, but PhpStorm isn't so sure
var transportInstance:GenericTransport = <GenericTransport> new transport(method, request, postData, callback);
transportInstance.Send();
} }
} }
} }

View File

@ -9,6 +9,7 @@ module Typertext.Json {
import HttpUrl = Typertext.Http.HttpUrl; import HttpUrl = Typertext.Http.HttpUrl;
import HttpPostData = Typertext.Http.HttpPostData; import HttpPostData = Typertext.Http.HttpPostData;
import HttpMethod = Typertext.Http.HttpMethod; import HttpMethod = Typertext.Http.HttpMethod;
import TransportConstructor = Typertext.Transport.TransportConstructor;
export class JsonRequest implements Typertext.GenericRequest<JsonResponseHandler> { export class JsonRequest implements Typertext.GenericRequest<JsonResponseHandler> {
private jsonType:string; private jsonType:string;
@ -62,8 +63,9 @@ module Typertext.Json {
* @param {HttpUrl} request * @param {HttpUrl} request
* @param {HttpPostData} postData * @param {HttpPostData} postData
* @param {JsonResponseHandler} callback * @param {JsonResponseHandler} callback
* @param {TransportConstructor} transport
*/ */
public RawRequest(method:HttpMethod, request:HttpUrl, postData:Typertext.Http.HttpPostData = {}, callback?:JsonResponseHandler) { public RawRequest(method:HttpMethod, request:HttpUrl, postData:Typertext.Http.HttpPostData = {}, callback?:JsonResponseHandler, transport?:TransportConstructor) {
//Ensure we have an executable callback //Ensure we have an executable callback
if (typeof callback != "function") { if (typeof callback != "function") {
//Make a request and ignore the response, throwing exceptions in async code can be weird //Make a request and ignore the response, throwing exceptions in async code can be weird
@ -82,7 +84,7 @@ module Typertext.Json {
//If it is then we can just pass it straight through to the JSON response //If it is then we can just pass it straight through to the JSON response
callback(JsonResponse.fromHttpResponse(response)); callback(JsonResponse.fromHttpResponse(response));
}); }, transport);
} }
} }
} }

View File

@ -1,7 +1,6 @@
module Typertext.Transport { module Typertext.Transport {
export class GenericTransport { export interface GenericTransport {
constructor(method:Typertext.Http.HttpMethod, request:Typertext.Http.HttpUrl, postData:Typertext.Http.HttpPostData, callback:Typertext.Http.HttpResponseHandler) { Send(): void;
Destroy(): void;
}
} }
} }

View File

@ -1,3 +1,7 @@
/**
* @namespace Typertext
* @module Transport
*/
module Typertext.Transport { module Typertext.Transport {
import HttpMethod = Typertext.Http.HttpMethod; import HttpMethod = Typertext.Http.HttpMethod;
import HttpUrl = Typertext.Http.HttpUrl import HttpUrl = Typertext.Http.HttpUrl
@ -13,7 +17,7 @@ module Typertext.Transport {
* @param {HttpResponseHandler} callback * @param {HttpResponseHandler} callback
* @returns {GenericTransport} * @returns {GenericTransport}
*/ */
static Transport(method:HttpMethod, request:HttpUrl, postData:HttpPostData, callback:HttpResponseHandler):GenericTransport { static Transport(method:HttpMethod, request:HttpUrl, postData:HttpPostData, callback:HttpResponseHandler):TransportConstructor {
//Prepare to test if we are in IE //Prepare to test if we are in IE
var ieTestDiv = document.createElement("div"); var ieTestDiv = document.createElement("div");
ieTestDiv.innerHTML = "<!--[if lte IE 7]><i></i><![endif]-->"; ieTestDiv.innerHTML = "<!--[if lte IE 7]><i></i><![endif]-->";
@ -31,13 +35,13 @@ module Typertext.Transport {
//If this is a CORS request in a modern browser //If this is a CORS request in a modern browser
if (!origin.CrossOriginCheck(origin) || !ieLte9) { if (!origin.CrossOriginCheck(origin) || !ieLte9) {
//Just use a standard XHR request //Just use a standard XHR request
return new XHR(method, request, postData, callback); return XHR;
} }
//Otherwise if we aren't cross protocol //Otherwise if we aren't cross protocol
if (origin.GetProtocol() === request.GetProtocol()) { if (origin.GetProtocol() === request.GetProtocol()) {
//Use IE's silly XDomainRequest //Use IE's silly XDomainRequest
return new XDR(method, request, postData, callback); return XDR;
} }
//Otherwise there is no supported transport //Otherwise there is no supported transport

View File

@ -0,0 +1,10 @@
module Typertext.Transport {
import HttpMethod = Typertext.Http.HttpMethod;
import HttpUrl = Typertext.Http.HttpUrl;
import HttpPostData = Typertext.Http.HttpPostData;
import HttpResponseHandler = Typertext.Http.HttpResponseHandler;
export interface TransportConstructor {
new (method:HttpMethod, request:HttpUrl, postData?:HttpPostData, callback?:HttpResponseHandler): GenericTransport;
}
}

View File

@ -6,51 +6,67 @@ module Typertext.Transport {
import HttpResponseStatus = Typertext.Http.HttpResponseStatus; import HttpResponseStatus = Typertext.Http.HttpResponseStatus;
import HttpResponse = Typertext.Http.HttpResponse; import HttpResponse = Typertext.Http.HttpResponse;
export class XDR extends GenericTransport { export class XDR implements GenericTransport {
private xdr:XDomainRequest;
private postData: HttpPostData;
private method:HttpMethod;
private request:HttpUrl;
private callback:HttpResponseHandler;
constructor(method:HttpMethod, request:HttpUrl, postData:HttpPostData = {}, callback:HttpResponseHandler = (c)=> null) { constructor(method:HttpMethod, request:HttpUrl, postData:HttpPostData = {}, callback:HttpResponseHandler = (c)=> null) {
super(method, request, postData, callback); //Store the request information
this.postData = postData;
this.method = method;
this.request = request;
this.callback = callback;
//Create a XDR //Create a XDR
var xdr = new XDomainRequest(); this.xdr = new XDomainRequest();
}
Send():void {
//and an interface to get the content type of the response //and an interface to get the content type of the response
var getHeader = (name:string):string => { var getHeader = (name:string):string => {
if (name.toLowerCase() === "content-type") { if (name.toLowerCase() === "content-type") {
return xdr.contentType; return this.xdr.contentType;
} }
return undefined; return undefined;
}; };
//Now to handle timeouts, //Now to handle timeouts,
xdr.ontimeout = () => { this.xdr.ontimeout = () => {
callback(new HttpResponse(HttpResponseStatus.timeout, (i:string)=>"", -1, "")); this.callback(new HttpResponse(HttpResponseStatus.timeout, (i:string)=>"", -1, ""));
}; };
//all errors (because XDR sucks), //all errors (because XDR sucks),
xdr.onerror = () => { this.xdr.onerror = () => {
callback(new HttpResponse(HttpResponseStatus.unknownError, getHeader, -1, xdr.responseText)); this.callback(new HttpResponse(HttpResponseStatus.unknownError, getHeader, -1, this.xdr.responseText));
}; };
//successes, //successes,
xdr.onload = () => { this.xdr.onload = () => {
callback(new HttpResponse(HttpResponseStatus.success, getHeader, 200, xdr.responseText)); this.callback(new HttpResponse(HttpResponseStatus.success, getHeader, 200, this.xdr.responseText));
}; };
//and even more stupidity (because XDR REALLY sucks). //and even more stupidity (because XDR REALLY sucks).
xdr.onprogress = () => null; this.xdr.onprogress = () => null;
//Finally, open the request //Finally, open the request
xdr.open(HttpMethod[method], request.ToString()); this.xdr.open(HttpMethod[this.method], this.request.ToString());
//and either send //and either send
if (method == HttpMethod.GET) { if (this.method == HttpMethod.GET) {
//a get request without data, //a get request without data,
xdr.send(); this.xdr.send();
return; return;
} }
//or send the post-data to the server (as text/plain, because XDR sucks) //or send the post-data to the server (as text/plain, because XDR sucks)
xdr.send(HttpUrl.UrlEncodeObject(postData)); this.xdr.send(HttpUrl.UrlEncodeObject(this.postData));
}
Destroy():void {
this.xdr.ontimeout = this.xdr.onerror = this.xdr.onload = this.xdr.onprogress = null;
this.xdr = null;
} }
} }
} }

View File

@ -6,59 +6,76 @@ module Typertext.Transport {
import HttpResponseStatus = Typertext.Http.HttpResponseStatus; import HttpResponseStatus = Typertext.Http.HttpResponseStatus;
import HttpResponse = Typertext.Http.HttpResponse; import HttpResponse = Typertext.Http.HttpResponse;
export class XHR extends GenericTransport { export class XHR implements GenericTransport {
private xhr:XMLHttpRequest;
private postData: HttpPostData;
private method:HttpMethod;
private request:HttpUrl;
private callback:HttpResponseHandler;
constructor(method:HttpMethod, request:HttpUrl, postData:HttpPostData = {}, callback:HttpResponseHandler = (c)=> null) { constructor(method:HttpMethod, request:HttpUrl, postData:HttpPostData = {}, callback:HttpResponseHandler = (c)=> null) {
super(method, request, postData, callback); //Store the request information
this.postData = postData;
this.method = method;
this.request = request;
this.callback = callback;
//Create a XHR //Create a XHR
var xhr = new XMLHttpRequest(); this.xhr = new XMLHttpRequest();
//And let us know when it does something //And let us know when it does something
xhr.onreadystatechange = ()=> { this.xhr.onreadystatechange = ()=> {
//If the request is complete //If the request is complete
if (xhr.readyState == 4) { if (this.xhr.readyState == 4) {
//Prepare a getter for the header //Prepare a getter for the header
var getHeader = (name:string):string => { var getHeader = (name:string):string => {
return xhr.getResponseHeader(name); return this.xhr.getResponseHeader(name);
}; };
//Check the status //Check the status
if (xhr.status == 200) { if (this.xhr.status == 200) {
//And either succeed //And either succeed
callback(new HttpResponse(HttpResponseStatus.success, getHeader, xhr.status, xhr.responseText)); this.callback(new HttpResponse(HttpResponseStatus.success, getHeader, this.xhr.status, this.xhr.responseText));
} else if (xhr.status >= 400 && xhr.status < 500) { } else if (this.xhr.status >= 400 && this.xhr.status < 500) {
//Or fail miserably //Or fail miserably
callback(new HttpResponse(HttpResponseStatus.clientError, getHeader, xhr.status, xhr.responseText)); this.callback(new HttpResponse(HttpResponseStatus.clientError, getHeader, this.xhr.status, this.xhr.responseText));
} else if (xhr.status >= 500 && xhr.status < 600) { } else if (this.xhr.status >= 500 && this.xhr.status < 600) {
//Again //Again
callback(new HttpResponse(HttpResponseStatus.serverError, getHeader, xhr.status, xhr.responseText)); this.callback(new HttpResponse(HttpResponseStatus.serverError, getHeader, this.xhr.status, this.xhr.responseText));
} else { } else {
//And again //And again
callback(new HttpResponse(HttpResponseStatus.unknownError, getHeader, xhr.status, xhr.responseText)); this.callback(new HttpResponse(HttpResponseStatus.unknownError, getHeader, this.xhr.status, this.xhr.responseText));
} }
} }
}; };
//Or if it times out //Or if it times out
xhr.ontimeout = () => { this.xhr.ontimeout = () => {
//And make a big deal of the failing //And make a big deal of the failing
callback(new HttpResponse(HttpResponseStatus.timeout, (i:string)=>"", -1, "")); this.callback(new HttpResponse(HttpResponseStatus.timeout, (i:string)=>"", -1, ""));
}; };
}
public Send() {
//Now connect //Now connect
xhr.open(HttpMethod[method], request.ToString(), true); this.xhr.open(HttpMethod[this.method], this.request.ToString(), true);
//And either send //And either send
if (method == HttpMethod.GET) { if (this.method == HttpMethod.GET) {
//A get request //A get request
xhr.send(); this.xhr.send();
return; return;
} }
//Or set the content-type //Or set the content-type
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); this.xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//And send the post-data to the server //And send the post-data to the server
xhr.send(HttpUrl.UrlEncodeObject(postData)); this.xhr.send(HttpUrl.UrlEncodeObject(this.postData));
}
public Destroy():void {
this.xhr.onreadystatechange = this.xhr.ontimeout = null;
this.xhr = null;
} }
} }
} }

View File

@ -5,7 +5,7 @@
"type": "git", "type": "git",
"url": "https://github.com/terribleplan/Typertext.git" "url": "https://github.com/terribleplan/Typertext.git"
}, },
"version": "0.6.1", "version": "0.7.0",
"devDependencies": { "devDependencies": {
"grunt": "~0.4.2", "grunt": "~0.4.2",
"grunt-cli": "~0.1.13", "grunt-cli": "~0.1.13",