Files
Angular-Cn/modules/angular2/src/http/backends/jsonp_backend.ts
T
Richard Sentino 256b2dc9b7 chore: remove ENUM_INDEX from facade
The ENUM_INDEX utility was added to return the index of an enum
consistently between Dart and TypeScript, so that the index
could be used to look up the name of the enum. Since dart is no
longer supported by Http, and since no other part of the framework
is using this function, it has been removed.

Closes #3843
2015-08-27 08:39:24 -07:00

98 lines
3.4 KiB
TypeScript

import {ConnectionBackend, Connection} from '../interfaces';
import {ReadyStates, RequestMethods} from '../enums';
import {Request} from '../static_request';
import {Response} from '../static_response';
import {ResponseOptions, BaseResponseOptions} from '../base_response_options';
import {Injectable} from 'angular2/di';
import {BrowserJsonp} from './browser_jsonp';
import {EventEmitter, ObservableWrapper} from 'angular2/src/core/facade/async';
import {StringWrapper, isPresent, makeTypeError} from 'angular2/src/core/facade/lang';
export class JSONPConnection implements Connection {
readyState: ReadyStates;
request: Request;
response: EventEmitter;
private _id: string;
private _script: Element;
private _responseData: any;
private _finished: boolean = false;
constructor(req: Request, private _dom: BrowserJsonp,
private baseResponseOptions?: ResponseOptions) {
if (req.method !== RequestMethods.GET) {
throw makeTypeError("JSONP requests must use GET request method.");
}
this.request = req;
this.response = new EventEmitter();
this.readyState = ReadyStates.LOADING;
this._id = _dom.nextRequestID();
_dom.exposeConnection(this._id, this);
// Workaround Dart
// url = url.replace(/=JSONP_CALLBACK(&|$)/, `generated method`);
let callback = _dom.requestCallback(this._id);
let url: string = req.url;
if (url.indexOf('=JSONP_CALLBACK&') > -1) {
url = StringWrapper.replace(url, '=JSONP_CALLBACK&', `=${callback}&`);
} else if (url.lastIndexOf('=JSONP_CALLBACK') === url.length - '=JSONP_CALLBACK'.length) {
url = StringWrapper.substring(url, 0, url.length - '=JSONP_CALLBACK'.length) + `=${callback}`;
}
let script = this._script = _dom.build(url);
script.addEventListener('load', (event) => {
if (this.readyState === ReadyStates.CANCELLED) return;
this.readyState = ReadyStates.DONE;
_dom.cleanup(script);
if (!this._finished) {
ObservableWrapper.callThrow(
this.response, makeTypeError('JSONP injected script did not invoke callback.'));
return;
}
let responseOptions = new ResponseOptions({body: this._responseData});
if (isPresent(this.baseResponseOptions)) {
responseOptions = this.baseResponseOptions.merge(responseOptions);
}
ObservableWrapper.callNext(this.response, new Response(responseOptions));
});
script.addEventListener('error', (error) => {
if (this.readyState === ReadyStates.CANCELLED) return;
this.readyState = ReadyStates.DONE;
_dom.cleanup(script);
ObservableWrapper.callThrow(this.response, error);
});
_dom.send(script);
}
finished(data?: any) {
// Don't leak connections
this._finished = true;
this._dom.removeConnection(this._id);
if (this.readyState === ReadyStates.CANCELLED) return;
this._responseData = data;
}
dispose(): void {
this.readyState = ReadyStates.CANCELLED;
let script = this._script;
this._script = null;
if (isPresent(script)) {
this._dom.cleanup(script);
}
ObservableWrapper.callReturn(this.response);
}
}
@Injectable()
export class JSONPBackend implements ConnectionBackend {
constructor(private _browserJSONP: BrowserJsonp, private _baseResponseOptions: ResponseOptions) {}
createConnection(request: Request): JSONPConnection {
return new JSONPConnection(request, this._browserJSONP, this._baseResponseOptions);
}
}