mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 20:11:24 +08:00
Implement XHR addEventListener/removeEventListener events.
- Used by the Angular XHRBackend service. - Only supporting 'load' and 'error' now. - Not implemented as weak events. Client responsible for detaching or not keeping a reference to the XHR object forever. (NG XHRBackend does so)
This commit is contained in:
@ -221,6 +221,35 @@ export function test_raises_onload_Event(done) {
|
|||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function test_xhr_events(done) {
|
||||||
|
let xhr = <any>new XMLHttpRequest();
|
||||||
|
|
||||||
|
let loadCallbackFired = false, loadEventFired = false;
|
||||||
|
xhr.onload = () => loadCallbackFired = true;
|
||||||
|
let badEvent = () => { throw new Error("Shouldn't call me") }
|
||||||
|
xhr.addEventListener('load', () => loadEventFired = true);
|
||||||
|
xhr.addEventListener('load', badEvent);
|
||||||
|
xhr.removeEventListener('load', badEvent);
|
||||||
|
|
||||||
|
xhr._errorFlag = false;
|
||||||
|
xhr._setReadyState(xhr.DONE);
|
||||||
|
TKUnit.assertTrue(loadCallbackFired);
|
||||||
|
TKUnit.assertTrue(loadEventFired);
|
||||||
|
|
||||||
|
let errorCallbackData = null, errorEventData = null;
|
||||||
|
xhr.onerror = (e) => errorCallbackData = e;
|
||||||
|
xhr.addEventListener('error', (e) => errorEventData = e);
|
||||||
|
xhr.addEventListener('error', badEvent);
|
||||||
|
xhr.removeEventListener('error', badEvent);
|
||||||
|
|
||||||
|
xhr._errorFlag = true;
|
||||||
|
xhr._setReadyState(xhr.DONE, 'error data');
|
||||||
|
TKUnit.assertEqual(errorCallbackData, 'error data');
|
||||||
|
TKUnit.assertEqual(errorEventData, 'error data');
|
||||||
|
|
||||||
|
done(null);
|
||||||
|
}
|
||||||
|
|
||||||
export function test_sets_status_and_statusText(done) {
|
export function test_sets_status_and_statusText(done) {
|
||||||
let xhr = new XMLHttpRequest();
|
let xhr = new XMLHttpRequest();
|
||||||
xhr.onreadystatechange = () => {
|
xhr.onreadystatechange = () => {
|
||||||
|
48
xhr/xhr.ts
48
xhr/xhr.ts
@ -15,7 +15,7 @@ export class XMLHttpRequest {
|
|||||||
public DONE = 4;
|
public DONE = 4;
|
||||||
|
|
||||||
public onload: () => void;
|
public onload: () => void;
|
||||||
public onerror: () => void;
|
public onerror: (any) => void;
|
||||||
|
|
||||||
private _options: http.HttpRequestOptions;
|
private _options: http.HttpRequestOptions;
|
||||||
private _readyState: number;
|
private _readyState: number;
|
||||||
@ -99,11 +99,36 @@ export class XMLHttpRequest {
|
|||||||
|
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
this._errorFlag = true;
|
this._errorFlag = true;
|
||||||
this._setReadyState(this.DONE);
|
this._setReadyState(this.DONE, e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _listeners: Map<string, Array<Function>> = new Map<string, Array<Function>>();
|
||||||
|
|
||||||
|
public addEventListener(eventName: string, handler: Function) {
|
||||||
|
if (eventName !== 'load' && eventName !== 'error') {
|
||||||
|
throw new Error('Event not supported: ' + eventName);
|
||||||
|
}
|
||||||
|
|
||||||
|
let handlers = this._listeners.get(eventName) || [];
|
||||||
|
handlers.push(handler);
|
||||||
|
this._listeners.set(eventName, handlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeEventListener(eventName: string, toDetach: Function) {
|
||||||
|
let handlers = this._listeners.get(eventName) || [];
|
||||||
|
handlers = handlers.filter((handler) => handler !== toDetach);
|
||||||
|
this._listeners.set(eventName, handlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private emitEvent(eventName: string, ...args: Array<any>) {
|
||||||
|
let handlers = this._listeners.get(eventName) || [];
|
||||||
|
handlers.forEach((handler) => {
|
||||||
|
handler(...args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public setRequestHeader(header: string, value: string) {
|
public setRequestHeader(header: string, value: string) {
|
||||||
if (types.isDefined(this._options) && types.isString(header) && types.isString(value)) {
|
if (types.isDefined(this._options) && types.isString(header) && types.isString(value)) {
|
||||||
this._options.headers[header] = value;
|
this._options.headers[header] = value;
|
||||||
@ -158,7 +183,7 @@ export class XMLHttpRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _setReadyState(value: number) {
|
private _setReadyState(value: number, error?: any) {
|
||||||
if (this._readyState !== value) {
|
if (this._readyState !== value) {
|
||||||
this._readyState = value;
|
this._readyState = value;
|
||||||
|
|
||||||
@ -168,11 +193,16 @@ export class XMLHttpRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this._readyState === this.DONE) {
|
if (this._readyState === this.DONE) {
|
||||||
if (this._errorFlag && types.isFunction(this.onerror)) {
|
if (this._errorFlag) {
|
||||||
this.onerror();
|
if (types.isFunction(this.onerror)) {
|
||||||
}
|
this.onerror(error);
|
||||||
if (!this._errorFlag && types.isFunction(this.onload)) {
|
}
|
||||||
this.onload();
|
this.emitEvent('error', error);
|
||||||
|
} else {
|
||||||
|
if (types.isFunction(this.onload)) {
|
||||||
|
this.onload();
|
||||||
|
}
|
||||||
|
this.emitEvent('load');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,4 +294,4 @@ export class FormData {
|
|||||||
|
|
||||||
return arr.join("&");
|
return arr.join("&");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user