75 lines
1.9 KiB
JavaScript
75 lines
1.9 KiB
JavaScript
|
import { AnonymousObservable, Disposable } from 'rx';
|
||
|
|
||
|
const root = typeof window !== 'undefined' ? window : {};
|
||
|
const trash = 'document' in root && root.document.createElement('div');
|
||
|
|
||
|
function destroy(element) {
|
||
|
trash.appendChild(element);
|
||
|
trash.innerHTML = '';
|
||
|
}
|
||
|
|
||
|
export function jsonp$(options) {
|
||
|
let id = 0;
|
||
|
if (typeof options === 'string') {
|
||
|
options = { url: options };
|
||
|
}
|
||
|
|
||
|
return new AnonymousObservable(function(o) {
|
||
|
const settings = {
|
||
|
jsonp: 'JSONPCallback',
|
||
|
async: true,
|
||
|
jsonpCallback: 'rxjsjsonpCallbackscallback_' + (id++).toString(36),
|
||
|
...options
|
||
|
};
|
||
|
|
||
|
let script = root.document.createElement('script');
|
||
|
script.type = 'text/javascript';
|
||
|
script.async = settings.async;
|
||
|
script.src = settings.url.replace(settings.jsonp, settings.jsonpCallback);
|
||
|
|
||
|
root[settings.jsonpCallback] = function(data) {
|
||
|
root[settings.jsonpCallback].called = true;
|
||
|
root[settings.jsonpCallback].data = data;
|
||
|
};
|
||
|
|
||
|
const handler = function(e) {
|
||
|
if (e.type === 'load' && !root[settings.jsonpCallback].called) {
|
||
|
e = { type: 'error' };
|
||
|
}
|
||
|
const status = e.type === 'error' ? 400 : 200;
|
||
|
const data = root[settings.jsonpCallback].data;
|
||
|
|
||
|
if (status === 200) {
|
||
|
o.onNext({
|
||
|
status: status,
|
||
|
responseType: 'jsonp',
|
||
|
response: data,
|
||
|
originalEvent: e
|
||
|
});
|
||
|
|
||
|
o.onCompleted();
|
||
|
} else {
|
||
|
o.onError({
|
||
|
type: 'error',
|
||
|
status: status,
|
||
|
originalEvent: e
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
|
||
|
script.onload = script.onreadystatechanged = script.onerror = handler;
|
||
|
|
||
|
const head = root.document.getElementsByTagName('head')[0] ||
|
||
|
root.document.documentElement;
|
||
|
|
||
|
head.insertBefore(script, head.firstChild);
|
||
|
|
||
|
return Disposable.create(() => {
|
||
|
script.onload = script.onreadystatechanged = script.onerror = null;
|
||
|
|
||
|
destroy(script);
|
||
|
script = null;
|
||
|
});
|
||
|
});
|
||
|
}
|