event-source-polyfill
Advanced tools
Comparing version 0.0.12 to 0.0.14
{ | ||
"name": "event-source-polyfill", | ||
"version": "0.0.12", | ||
"version": "0.0.14", | ||
"main": "src/eventsource.js" | ||
} |
@@ -5,3 +5,3 @@ { | ||
"description": "a polyfill for http://www.w3.org/TR/eventsource/", | ||
"version": "0.0.12", | ||
"version": "0.0.14", | ||
"keywords": [ | ||
@@ -8,0 +8,0 @@ "sse", |
{ | ||
"name": "event-source-polyfill", | ||
"version": "0.0.12", | ||
"version": "0.0.14", | ||
"description": "A polyfill for http://www.w3.org/TR/eventsource/ ", | ||
@@ -5,0 +5,0 @@ "main": "src/eventsource.js", |
@@ -1,2 +0,2 @@ | ||
EventSource polyfill - http://www.w3.org/TR/eventsource/ | ||
EventSource polyfill - https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events | ||
======================================================== | ||
@@ -3,0 +3,0 @@ |
@@ -19,2 +19,6 @@ /** @license | ||
var document = global.document; | ||
var Promise = global.Promise; | ||
var fetch = global.fetch; | ||
var Response = global.Response; | ||
var TextDecoder = global.TextDecoder; | ||
@@ -29,2 +33,68 @@ if (Object.create == null) { | ||
// ? | ||
if (Promise != undefined && Promise.prototype["finally"] == undefined) { | ||
Promise.prototype["finally"] = function (callback) { | ||
return this.then(function (result) { | ||
return Promise.resolve(callback()).then(function () { | ||
return result; | ||
}); | ||
}, function (error) { | ||
return Promise.resolve(callback()).then(function () { | ||
throw error; | ||
}); | ||
}); | ||
}; | ||
} | ||
// Firefox < 40 (no "stream" option), IE, Edge | ||
function TextDecoderPolyfill() { | ||
} | ||
//TODO: stream option support | ||
TextDecoderPolyfill.prototype.decode = function (octets) { | ||
var string = ""; | ||
var i = 0; | ||
while (i < octets.length) { | ||
var octet = octets[i]; | ||
var bytesNeeded = 0; | ||
var codePoint = 0; | ||
if (octet <= 0x7F) { | ||
bytesNeeded = 0; | ||
codePoint = octet & 0xFF; | ||
} else if (octet <= 0xDF) { | ||
bytesNeeded = 1; | ||
codePoint = octet & 0x1F; | ||
} else if (octet <= 0xEF) { | ||
bytesNeeded = 2; | ||
codePoint = octet & 0x0F; | ||
} else if (octet <= 0xF4) { | ||
bytesNeeded = 3; | ||
codePoint = octet & 0x07; | ||
} | ||
if (octets.length - i - bytesNeeded > 0) { | ||
var k = 0; | ||
while (k < bytesNeeded) { | ||
octet = octets[i + k + 1]; | ||
codePoint = (codePoint << 6) | (octet & 0x3F); | ||
k += 1; | ||
} | ||
} else { | ||
codePoint = 0xFFFD; | ||
bytesNeeded = octets.length - i; | ||
} | ||
if (codePoint > 0xFFFF) { | ||
string += String.fromCharCode(0xD800 + ((codePoint - 0xFFFF - 1) >> 10)); | ||
string += String.fromCharCode(0xDC00 + ((codePoint - 0xFFFF - 1) & 0x3FF)); | ||
} else { | ||
string += String.fromCharCode(codePoint); | ||
} | ||
i += bytesNeeded + 1; | ||
} | ||
return string; | ||
}; | ||
if (TextDecoder == undefined) { | ||
TextDecoder = TextDecoderPolyfill; | ||
} | ||
var k = function () { | ||
@@ -193,3 +263,3 @@ }; | ||
if ("contentType" in xhr) { | ||
url += (url.indexOf("?", 0) === -1 ? "?" : "&") + "padding=true"; | ||
url += (url.indexOf("?") === -1 ? "?" : "&") + "padding=true"; | ||
} | ||
@@ -218,2 +288,5 @@ xhr.open(method, url, true); | ||
}; | ||
XHRWrapper.prototype.getAllResponseHeaders = function () { | ||
return this._xhr.getAllResponseHeaders != undefined ? this._xhr.getAllResponseHeaders() : ""; | ||
}; | ||
XHRWrapper.prototype.send = function () { | ||
@@ -246,8 +319,29 @@ // loading indicator in Safari < ? (6), Chrome < 14, Firefox | ||
function XHRTransport(xhr) { | ||
this._xhr = new XHRWrapper(xhr); | ||
function toLowerCase(name) { | ||
return name.replace(/[A-Z]/g, function (c) { | ||
return String.fromCharCode(c.charCodeAt(0) + 0x20); | ||
}); | ||
} | ||
XHRTransport.prototype.open = function (onStartCallback, onProgressCallback, onFinishCallback, url, withCredentials, headers) { | ||
var xhr = this._xhr; | ||
function HeadersPolyfill(all) { | ||
// Get headers: implemented according to mozilla's example code: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/getAllResponseHeaders#Example | ||
var map = Object.create(null); | ||
var array = all.split("\r\n"); | ||
for (var i = 0; i < array.length; i += 1) { | ||
var line = array[i]; | ||
var parts = line.split(": "); | ||
var name = parts.shift(); | ||
var value = parts.join(": "); | ||
map[toLowerCase(name)] = value; | ||
} | ||
this._map = map; | ||
} | ||
HeadersPolyfill.prototype.get = function (name) { | ||
return this._map[toLowerCase(name)]; | ||
}; | ||
function XHRTransport() { | ||
} | ||
XHRTransport.prototype.open = function (xhr, onStartCallback, onProgressCallback, onFinishCallback, url, withCredentials, headers) { | ||
xhr.open("GET", url); | ||
@@ -266,3 +360,6 @@ var offset = 0; | ||
var contentType = xhr.getResponseHeader("Content-Type"); | ||
onStartCallback(status, statusText, contentType); | ||
var headers = xhr.getAllResponseHeaders(); | ||
onStartCallback(status, statusText, contentType, new HeadersPolyfill(headers), function () { | ||
xhr.abort(); | ||
}); | ||
} else if (xhr.readyState === 4) { | ||
@@ -281,6 +378,45 @@ onFinishCallback(); | ||
}; | ||
function HeadersWrapper(headers) { | ||
this._headers = headers; | ||
} | ||
HeadersWrapper.prototype.get = function (name) { | ||
return this._headers.get(name); | ||
}; | ||
XHRTransport.prototype.cancel = function () { | ||
var xhr = this._xhr; | ||
xhr.abort(); | ||
function FetchTransport() { | ||
} | ||
FetchTransport.prototype.open = function (xhr, onStartCallback, onProgressCallback, onFinishCallback, url, withCredentials, headers) { | ||
// cache: "no-store" | ||
// https://bugs.chromium.org/p/chromium/issues/detail?id=453190 | ||
var textDecoder = new TextDecoder(); | ||
fetch(url, { | ||
headers: headers, | ||
credentials: withCredentials ? "include" : "same-origin" | ||
}).then(function (response) { | ||
var reader = response.body.getReader(); | ||
onStartCallback(response.status, response.statusText, response.headers.get("Content-Type"), new HeadersWrapper(response.headers), function () { | ||
reader.cancel(); | ||
}); | ||
return new Promise(function (resolve, reject) { | ||
var readNextChunk = function () { | ||
reader.read().then(function (result) { | ||
if (result.done) { | ||
//Note: bytes in textDecoder are ignored | ||
resolve(undefined); | ||
} else { | ||
var chunk = textDecoder.decode(result.value, {stream: true}); | ||
onProgressCallback(chunk); | ||
readNextChunk(); | ||
} | ||
})["catch"](function (error) { | ||
reject(error); | ||
}); | ||
}; | ||
readNextChunk(); | ||
}); | ||
})["finally"](function () { | ||
onFinishCallback(); | ||
}); | ||
}; | ||
@@ -367,2 +503,11 @@ | ||
function ConnectionEvent(type, options) { | ||
Event.call(this, type); | ||
this.status = options.status; | ||
this.statusText = options.statusText; | ||
this.headers = options.headers; | ||
} | ||
ConnectionEvent.prototype = Object.create(Event.prototype); | ||
var WAITING = -1; | ||
@@ -421,2 +566,10 @@ var CONNECTING = 0; | ||
function getBestTransport() { | ||
return XMLHttpRequest && "withCredentials" in XMLHttpRequest.prototype | ||
? XMLHttpRequest | ||
: XDomainRequest; | ||
} | ||
var isFetchSupported = fetch != undefined && Response != undefined && "body" in Response.prototype; | ||
function start(es, url, options) { | ||
@@ -433,4 +586,6 @@ url = String(url); | ||
var headers = options != undefined && options.headers != undefined ? JSON.parse(JSON.stringify(options.headers)) : undefined; | ||
var CurrentTransport = options != undefined && options.Transport != undefined ? options.Transport : (XDomainRequest != undefined ? XDomainRequest : XMLHttpRequest); | ||
var transport = new XHRTransport(new CurrentTransport()); | ||
var CurrentTransport = options != undefined && options.Transport != undefined ? options.Transport : getBestTransport(); | ||
var xhr = isFetchSupported ? undefined : new XHRWrapper(new CurrentTransport()); | ||
var transport = isFetchSupported ? new FetchTransport() : new XHRTransport(); | ||
var cancelFunction = undefined; | ||
var timeout = 0; | ||
@@ -447,4 +602,5 @@ var currentState = WAITING; | ||
var onStart = function (status, statusText, contentType) { | ||
var onStart = function (status, statusText, contentType, headers, cancel) { | ||
if (currentState === CONNECTING) { | ||
cancelFunction = cancel; | ||
if (status === 200 && contentType != undefined && contentTypeRegExp.test(contentType)) { | ||
@@ -455,3 +611,7 @@ currentState = OPEN; | ||
es.readyState = OPEN; | ||
var event = new Event("open"); | ||
var event = new ConnectionEvent("open", { | ||
status: status, | ||
statusText: statusText, | ||
headers: headers | ||
}); | ||
es.dispatchEvent(event); | ||
@@ -471,3 +631,7 @@ fire(es, es.onopen, event); | ||
close(); | ||
var event = new Event("error"); | ||
var event = new ConnectionEvent("error", { | ||
status: status, | ||
statusText: statusText, | ||
headers: headers | ||
}); | ||
es.dispatchEvent(event); | ||
@@ -590,3 +754,6 @@ fire(es, es.onerror, event); | ||
currentState = CLOSED; | ||
transport.cancel(); | ||
if (cancelFunction != undefined) { | ||
cancelFunction(); | ||
cancelFunction = undefined; | ||
} | ||
if (timeout !== 0) { | ||
@@ -603,5 +770,6 @@ clearTimeout(timeout); | ||
if (currentState !== WAITING) { | ||
if (!wasActivity) { | ||
if (!wasActivity && cancelFunction != undefined) { | ||
throwError(new Error("No activity within " + heartbeatTimeout + " milliseconds. Reconnecting.")); | ||
transport.cancel(); | ||
cancelFunction(); | ||
cancelFunction = undefined; | ||
} else { | ||
@@ -633,5 +801,6 @@ wasActivity = false; | ||
var requestURL = url; | ||
if (url.slice(0, 5) !== "data:" && | ||
url.slice(0, 5) !== "blob:") { | ||
requestURL = url + (url.indexOf("?", 0) === -1 ? "?" : "&") + "lastEventId=" + encodeURIComponent(lastEventId); | ||
if (url.slice(0, 5) !== "data:" && url.slice(0, 5) !== "blob:") { | ||
if (lastEventId !== "") { | ||
requestURL += (url.indexOf("?") === -1 ? "?" : "&") + "lastEventId=" + encodeURIComponent(lastEventId); | ||
} | ||
} | ||
@@ -648,3 +817,3 @@ var requestHeaders = {}; | ||
try { | ||
transport.open(onStart, onProgress, onFinish, requestURL, withCredentials, requestHeaders); | ||
transport.open(xhr, onStart, onProgress, onFinish, requestURL, withCredentials, requestHeaders); | ||
} catch (error) { | ||
@@ -651,0 +820,0 @@ close(); |
@@ -6,2 +6,2 @@ /** @license | ||
*/ | ||
!function(a){"use strict";function b(a){this.withCredentials=!1,this.responseType="",this.readyState=0,this.status=0,this.statusText="",this.responseText="",this.onprogress=p,this.onreadystatechange=p,this._contentType="",this._xhr=a,this._sendTimeout=0,this._abort=p}function c(a){this._xhr=new b(a)}function d(){this._listeners=Object.create(null)}function e(a){j(function(){throw a},0)}function f(a){this.type=a,this.target=void 0}function g(a,b){f.call(this,a),this.data=b.data,this.lastEventId=b.lastEventId}function h(a,b){d.call(this),this.onopen=void 0,this.onmessage=void 0,this.onerror=void 0,this.url=void 0,this.readyState=void 0,this.withCredentials=void 0,this._close=void 0,i(this,a,b)}function i(a,b,d){b=String(b);var h=void 0!=d&&Boolean(d.withCredentials),i=D(1e3),n=D(45e3),o="",p=i,A=!1,B=void 0!=d&&void 0!=d.headers?JSON.parse(JSON.stringify(d.headers)):void 0,F=void 0!=d&&void 0!=d.Transport?d.Transport:void 0!=m?m:l,G=new c(new F),H=0,I=q,J="",K="",L="",M="",N=v,O=0,P=0,Q=function(b,c,d){if(I===r)if(200===b&&void 0!=d&&z.test(d)){I=s,A=!0,p=i,a.readyState=s;var g=new f("open");a.dispatchEvent(g),E(a,a.onopen,g)}else{var h="";200!==b?(c&&(c=c.replace(/\s+/g," ")),h="EventSource's response has a status "+b+" "+c+" that is not 200. Aborting the connection."):h="EventSource's response has a Content-Type specifying an unsupported type: "+(void 0==d?"-":d.replace(/\s+/g," "))+". Aborting the connection.",e(new Error(h)),T();var g=new f("error");a.dispatchEvent(g),E(a,a.onerror,g)}},R=function(b){if(I===s){for(var c=-1,d=0;d<b.length;d+=1){var e=b.charCodeAt(d);(e==="\n".charCodeAt(0)||e==="\r".charCodeAt(0))&&(c=d)}var f=(-1!==c?M:"")+b.slice(0,c+1);M=(-1===c?M:"")+b.slice(c+1),""!==f&&(A=!0);for(var h=0;h<f.length;h+=1){var e=f.charCodeAt(h);if(N===u&&e==="\n".charCodeAt(0))N=v;else if(N===u&&(N=v),e==="\r".charCodeAt(0)||e==="\n".charCodeAt(0)){if(N!==v){N===w&&(P=h+1);var l=f.slice(O,P-1),m=f.slice(P+(h>P&&f.charCodeAt(P)===" ".charCodeAt(0)?1:0),h);"data"===l?(J+="\n",J+=m):"id"===l?K=m:"event"===l?L=m:"retry"===l?(i=C(m,i),p=i):"heartbeatTimeout"===l&&(n=C(m,n),0!==H&&(k(H),H=j(function(){U()},n)))}if(N===v){if(""!==J){o=K,""===L&&(L="message");var q=new g(L,{data:J.slice(1),lastEventId:K});if(a.dispatchEvent(q),"message"===L&&E(a,a.onmessage,q),I===t)return}J="",L=""}N=e==="\r".charCodeAt(0)?u:v}else N===v&&(O=h,N=w),N===w?e===":".charCodeAt(0)&&(P=h+1,N=x):N===x&&(N=y)}}},S=function(){if(I===s||I===r){I=q,0!==H&&(k(H),H=0),H=j(function(){U()},p),p=D(Math.min(16*i,2*p)),a.readyState=r;var b=new f("error");a.dispatchEvent(b),E(a,a.onerror,b)}},T=function(){I=t,G.cancel(),0!==H&&(k(H),H=0),a.readyState=t},U=function(){if(H=0,I!==q)return void(A?(A=!1,H=j(function(){U()},n)):(e(new Error("No activity within "+n+" milliseconds. Reconnecting.")),G.cancel()));A=!1,H=j(function(){U()},n),I=r,J="",L="",K=o,M="",O=0,P=0,N=v;var a=b;"data:"!==b.slice(0,5)&&"blob:"!==b.slice(0,5)&&(a=b+(-1===b.indexOf("?",0)?"?":"&")+"lastEventId="+encodeURIComponent(o));var c={};if(c.Accept="text/event-stream",void 0!=B)for(var d in B)Object.prototype.hasOwnProperty.call(B,d)&&(c[d]=B[d]);try{G.open(Q,R,S,a,h,c)}catch(f){throw T(),f}};a.url=b,a.readyState=r,a.withCredentials=h,a._close=T,U()}var j=a.setTimeout,k=a.clearTimeout,l=a.XMLHttpRequest,m=a.XDomainRequest,n=a.EventSource,o=a.document;null==Object.create&&(Object.create=function(a){function b(){}return b.prototype=a,new b});var p=function(){};b.prototype.open=function(a,b){this._abort(!0);var c=this,d=this._xhr,e=1,f=0;this._abort=function(a){0!==c._sendTimeout&&(k(c._sendTimeout),c._sendTimeout=0),(1===e||2===e||3===e)&&(e=4,d.onload=p,d.onerror=p,d.onabort=p,d.onprogress=p,d.onreadystatechange=p,d.abort(),0!==f&&(k(f),f=0),a||(c.readyState=4,c.onreadystatechange())),e=0};var g=function(){if(1===e){var a=0,b="",f=void 0;if("contentType"in d)a=200,b="OK",f=d.contentType;else try{a=d.status,b=d.statusText,f=d.getResponseHeader("Content-Type")}catch(g){a=0,b="",f=void 0}0!==a&&(e=2,c.readyState=2,c.status=a,c.statusText=b,c._contentType=f,c.onreadystatechange())}},h=function(){if(g(),2===e||3===e){e=3;var a="";try{a=d.responseText}catch(b){}c.readyState=3,c.responseText=a,c.onprogress()}},i=function(){h(),(1===e||2===e||3===e)&&(e=4,0!==f&&(k(f),f=0),c.readyState=4,c.onreadystatechange())},m=function(){void 0!=d&&(4===d.readyState?i():3===d.readyState?h():2===d.readyState&&g())},n=function(){f=j(function(){n()},500),3===d.readyState&&h()};d.onload=i,d.onerror=i,d.onabort=i,"sendAsBinary"in l.prototype||"mozAnon"in l.prototype||(d.onprogress=h),d.onreadystatechange=m,"contentType"in d&&(b+=(-1===b.indexOf("?",0)?"?":"&")+"padding=true"),d.open(a,b,!0),"readyState"in d&&(f=j(function(){n()},0))},b.prototype.abort=function(){this._abort(!1)},b.prototype.getResponseHeader=function(a){return this._contentType},b.prototype.setRequestHeader=function(a,b){var c=this._xhr;"setRequestHeader"in c&&c.setRequestHeader(a,b)},b.prototype.send=function(){if(!("ontimeout"in l.prototype)&&void 0!=o&&void 0!=o.readyState&&"complete"!==o.readyState){var a=this;return void(a._sendTimeout=j(function(){a._sendTimeout=0,a.send()},4))}var b=this._xhr;b.withCredentials=this.withCredentials,b.responseType=this.responseType;try{b.send(void 0)}catch(c){throw c}},c.prototype.open=function(a,b,c,d,e,f){var g=this._xhr;g.open("GET",d);var h=0;g.onprogress=function(){var a=g.responseText,c=a.slice(h);h+=c.length,b(c)},g.onreadystatechange=function(){if(2===g.readyState){var b=g.status,d=g.statusText,e=g.getResponseHeader("Content-Type");a(b,d,e)}else 4===g.readyState&&c()},g.withCredentials=e,g.responseType="text";for(var i in f)Object.prototype.hasOwnProperty.call(f,i)&&g.setRequestHeader(i,f[i]);g.send()},c.prototype.cancel=function(){var a=this._xhr;a.abort()},d.prototype.dispatchEvent=function(a){a.target=this;var b=this._listeners[a.type];if(void 0!=b)for(var c=b.length,d=0;c>d;d+=1){var f=b[d];try{"function"==typeof f.handleEvent?f.handleEvent(a):f.call(this,a)}catch(g){e(g)}}},d.prototype.addEventListener=function(a,b){a=String(a);var c=this._listeners,d=c[a];void 0==d&&(d=[],c[a]=d);for(var e=!1,f=0;f<d.length;f+=1)d[f]===b&&(e=!0);e||d.push(b)},d.prototype.removeEventListener=function(a,b){a=String(a);var c=this._listeners,d=c[a];if(void 0!=d){for(var e=[],f=0;f<d.length;f+=1)d[f]!==b&&e.push(d[f]);0===e.length?delete c[a]:c[a]=e}},g.prototype=Object.create(f.prototype);var q=-1,r=0,s=1,t=2,u=-1,v=0,w=1,x=2,y=3,z=/^text\/event\-stream;?(\s*charset\=utf\-8)?$/i,A=1e3,B=18e6,C=function(a,b){var c=parseInt(a,10);return c!==c&&(c=b),D(c)},D=function(a){return Math.min(Math.max(a,A),B)},E=function(a,b,c){try{"function"==typeof b&&b.call(a,c)}catch(d){e(d)}};h.prototype=Object.create(d.prototype),h.prototype.CONNECTING=r,h.prototype.OPEN=s,h.prototype.CLOSED=t,h.prototype.close=function(){this._close()},h.CONNECTING=r,h.OPEN=s,h.CLOSED=t,h.prototype.withCredentials=void 0,a.EventSourcePolyfill=h,a.NativeEventSource=n,void 0==l||void 0!=n&&"withCredentials"in n.prototype||(a.EventSource=h)}("undefined"!=typeof window?window:this); | ||
!function(a){"use strict";function b(a){this.withCredentials=!1,this.responseType="",this.readyState=0,this.status=0,this.statusText="",this.responseText="",this.onprogress=q,this.onreadystatechange=q,this._contentType="",this._xhr=a,this._sendTimeout=0,this._abort=q}function c(a){this._xhr=new b(a)}function d(){this._listeners=Object.create(null)}function e(a){k(function(){throw a},0)}function f(a){this.type=a,this.target=void 0}function g(a,b){f.call(this,a),this.data=b.data,this.lastEventId=b.lastEventId}function h(a,b){d.call(this),this.onopen=void 0,this.onmessage=void 0,this.onerror=void 0,this.url=void 0,this.readyState=void 0,this.withCredentials=void 0,this._close=void 0,j(this,a,b)}function i(){return m&&"withCredentials"in m.prototype?m:n}function j(a,b,d){b=String(b);var h=void 0!=d&&Boolean(d.withCredentials),j=E(1e3),m=void 0!=d&&void 0!=d.heartbeatTimeout?D(d.heartbeatTimeout,45e3):E(45e3),n="",o=j,p=!1,q=void 0!=d&&void 0!=d.headers?JSON.parse(JSON.stringify(d.headers)):void 0,B=void 0!=d&&void 0!=d.Transport?d.Transport:i(),C=new c(new B),G=0,H=r,I="",J="",K="",L="",M=w,N=0,O=0,P=function(b,c,d){if(H===s)if(200===b&&void 0!=d&&A.test(d)){H=t,p=!0,o=j,a.readyState=t;var g=new f("open");a.dispatchEvent(g),F(a,a.onopen,g)}else{var h="";200!==b?(c&&(c=c.replace(/\s+/g," ")),h="EventSource's response has a status "+b+" "+c+" that is not 200. Aborting the connection."):h="EventSource's response has a Content-Type specifying an unsupported type: "+(void 0==d?"-":d.replace(/\s+/g," "))+". Aborting the connection.",e(new Error(h)),S();var g=new f("error");a.dispatchEvent(g),F(a,a.onerror,g)}},Q=function(b){if(H===t){for(var c=-1,d=0;d<b.length;d+=1){var e=b.charCodeAt(d);(e==="\n".charCodeAt(0)||e==="\r".charCodeAt(0))&&(c=d)}var f=(-1!==c?L:"")+b.slice(0,c+1);L=(-1===c?L:"")+b.slice(c+1),""!==f&&(p=!0);for(var h=0;h<f.length;h+=1){var e=f.charCodeAt(h);if(M===v&&e==="\n".charCodeAt(0))M=w;else if(M===v&&(M=w),e==="\r".charCodeAt(0)||e==="\n".charCodeAt(0)){if(M!==w){M===x&&(O=h+1);var i=f.slice(N,O-1),q=f.slice(O+(h>O&&f.charCodeAt(O)===" ".charCodeAt(0)?1:0),h);"data"===i?(I+="\n",I+=q):"id"===i?J=q:"event"===i?K=q:"retry"===i?(j=D(q,j),o=j):"heartbeatTimeout"===i&&(m=D(q,m),0!==G&&(l(G),G=k(function(){T()},m)))}if(M===w){if(""!==I){n=J,""===K&&(K="message");var r=new g(K,{data:I.slice(1),lastEventId:J});if(a.dispatchEvent(r),"message"===K&&F(a,a.onmessage,r),H===u)return}I="",K=""}M=e==="\r".charCodeAt(0)?v:w}else M===w&&(N=h,M=x),M===x?e===":".charCodeAt(0)&&(O=h+1,M=y):M===y&&(M=z)}}},R=function(){if(H===t||H===s){H=r,0!==G&&(l(G),G=0),G=k(function(){T()},o),o=E(Math.min(16*j,2*o)),a.readyState=s;var b=new f("error");a.dispatchEvent(b),F(a,a.onerror,b)}},S=function(){H=u,C.cancel(),0!==G&&(l(G),G=0),a.readyState=u},T=function(){if(G=0,H!==r)return void(p?(p=!1,G=k(function(){T()},m)):(e(new Error("No activity within "+m+" milliseconds. Reconnecting.")),C.cancel()));p=!1,G=k(function(){T()},m),H=s,I="",K="",J=n,L="",N=0,O=0,M=w;var a=b;"data:"!==b.slice(0,5)&&"blob:"!==b.slice(0,5)&&(a=b+(-1===b.indexOf("?",0)?"?":"&")+"lastEventId="+encodeURIComponent(n));var c={};if(c.Accept="text/event-stream",void 0!=q)for(var d in q)Object.prototype.hasOwnProperty.call(q,d)&&(c[d]=q[d]);try{C.open(P,Q,R,a,h,c)}catch(f){throw S(),f}};a.url=b,a.readyState=s,a.withCredentials=h,a._close=S,T()}var k=a.setTimeout,l=a.clearTimeout,m=a.XMLHttpRequest,n=a.XDomainRequest,o=a.EventSource,p=a.document;null==Object.create&&(Object.create=function(a){function b(){}return b.prototype=a,new b});var q=function(){};b.prototype.open=function(a,b){this._abort(!0);var c=this,d=this._xhr,e=1,f=0;this._abort=function(a){0!==c._sendTimeout&&(l(c._sendTimeout),c._sendTimeout=0),(1===e||2===e||3===e)&&(e=4,d.onload=q,d.onerror=q,d.onabort=q,d.onprogress=q,d.onreadystatechange=q,d.abort(),0!==f&&(l(f),f=0),a||(c.readyState=4,c.onreadystatechange())),e=0};var g=function(){if(1===e){var a=0,b="",f=void 0;if("contentType"in d)a=200,b="OK",f=d.contentType;else try{a=d.status,b=d.statusText,f=d.getResponseHeader("Content-Type")}catch(g){a=0,b="",f=void 0}0!==a&&(e=2,c.readyState=2,c.status=a,c.statusText=b,c._contentType=f,c.onreadystatechange())}},h=function(){if(g(),2===e||3===e){e=3;var a="";try{a=d.responseText}catch(b){}c.readyState=3,c.responseText=a,c.onprogress()}},i=function(){h(),(1===e||2===e||3===e)&&(e=4,0!==f&&(l(f),f=0),c.readyState=4,c.onreadystatechange())},j=function(){void 0!=d&&(4===d.readyState?i():3===d.readyState?h():2===d.readyState&&g())},n=function(){f=k(function(){n()},500),3===d.readyState&&h()};d.onload=i,d.onerror=i,d.onabort=i,"sendAsBinary"in m.prototype||"mozAnon"in m.prototype||(d.onprogress=h),d.onreadystatechange=j,"contentType"in d&&(b+=(-1===b.indexOf("?",0)?"?":"&")+"padding=true"),d.open(a,b,!0),"readyState"in d&&(f=k(function(){n()},0))},b.prototype.abort=function(){this._abort(!1)},b.prototype.getResponseHeader=function(a){return this._contentType},b.prototype.setRequestHeader=function(a,b){var c=this._xhr;"setRequestHeader"in c&&c.setRequestHeader(a,b)},b.prototype.send=function(){if(!("ontimeout"in m.prototype)&&void 0!=p&&void 0!=p.readyState&&"complete"!==p.readyState){var a=this;return void(a._sendTimeout=k(function(){a._sendTimeout=0,a.send()},4))}var b=this._xhr;b.withCredentials=this.withCredentials,b.responseType=this.responseType;try{b.send(void 0)}catch(c){throw c}},c.prototype.open=function(a,b,c,d,e,f){var g=this._xhr;g.open("GET",d);var h=0;g.onprogress=function(){var a=g.responseText,c=a.slice(h);h+=c.length,b(c)},g.onreadystatechange=function(){if(2===g.readyState){var b=g.status,d=g.statusText,e=g.getResponseHeader("Content-Type");a(b,d,e)}else 4===g.readyState&&c()},g.withCredentials=e,g.responseType="text";for(var i in f)Object.prototype.hasOwnProperty.call(f,i)&&g.setRequestHeader(i,f[i]);g.send()},c.prototype.cancel=function(){var a=this._xhr;a.abort()},d.prototype.dispatchEvent=function(a){a.target=this;var b=this._listeners[a.type];if(void 0!=b)for(var c=b.length,d=0;c>d;d+=1){var f=b[d];try{"function"==typeof f.handleEvent?f.handleEvent(a):f.call(this,a)}catch(g){e(g)}}},d.prototype.addEventListener=function(a,b){a=String(a);var c=this._listeners,d=c[a];void 0==d&&(d=[],c[a]=d);for(var e=!1,f=0;f<d.length;f+=1)d[f]===b&&(e=!0);e||d.push(b)},d.prototype.removeEventListener=function(a,b){a=String(a);var c=this._listeners,d=c[a];if(void 0!=d){for(var e=[],f=0;f<d.length;f+=1)d[f]!==b&&e.push(d[f]);0===e.length?delete c[a]:c[a]=e}},g.prototype=Object.create(f.prototype);var r=-1,s=0,t=1,u=2,v=-1,w=0,x=1,y=2,z=3,A=/^text\/event\-stream;?(\s*charset\=utf\-8)?$/i,B=1e3,C=18e6,D=function(a,b){var c=parseInt(a,10);return c!==c&&(c=b),E(c)},E=function(a){return Math.min(Math.max(a,B),C)},F=function(a,b,c){try{"function"==typeof b&&b.call(a,c)}catch(d){e(d)}};h.prototype=Object.create(d.prototype),h.prototype.CONNECTING=s,h.prototype.OPEN=t,h.prototype.CLOSED=u,h.prototype.close=function(){this._close()},h.CONNECTING=s,h.OPEN=t,h.CLOSED=u,h.prototype.withCredentials=void 0,a.EventSourcePolyfill=h,a.NativeEventSource=o,void 0==m||void 0!=o&&"withCredentials"in o.prototype||(a.EventSource=h)}("undefined"!=typeof window?window:this); |
@@ -19,2 +19,6 @@ /** @license | ||
var document = global.document; | ||
var Promise = global.Promise; | ||
var fetch = global.fetch; | ||
var Response = global.Response; | ||
var TextDecoder = global.TextDecoder; | ||
@@ -29,2 +33,68 @@ if (Object.create == null) { | ||
// ? | ||
if (Promise != undefined && Promise.prototype["finally"] == undefined) { | ||
Promise.prototype["finally"] = function (callback) { | ||
return this.then(function (result) { | ||
return Promise.resolve(callback()).then(function () { | ||
return result; | ||
}); | ||
}, function (error) { | ||
return Promise.resolve(callback()).then(function () { | ||
throw error; | ||
}); | ||
}); | ||
}; | ||
} | ||
// Firefox < 40 (no "stream" option), IE, Edge | ||
function TextDecoderPolyfill() { | ||
} | ||
//TODO: stream option support | ||
TextDecoderPolyfill.prototype.decode = function (octets) { | ||
var string = ""; | ||
var i = 0; | ||
while (i < octets.length) { | ||
var octet = octets[i]; | ||
var bytesNeeded = 0; | ||
var codePoint = 0; | ||
if (octet <= 0x7F) { | ||
bytesNeeded = 0; | ||
codePoint = octet & 0xFF; | ||
} else if (octet <= 0xDF) { | ||
bytesNeeded = 1; | ||
codePoint = octet & 0x1F; | ||
} else if (octet <= 0xEF) { | ||
bytesNeeded = 2; | ||
codePoint = octet & 0x0F; | ||
} else if (octet <= 0xF4) { | ||
bytesNeeded = 3; | ||
codePoint = octet & 0x07; | ||
} | ||
if (octets.length - i - bytesNeeded > 0) { | ||
var k = 0; | ||
while (k < bytesNeeded) { | ||
octet = octets[i + k + 1]; | ||
codePoint = (codePoint << 6) | (octet & 0x3F); | ||
k += 1; | ||
} | ||
} else { | ||
codePoint = 0xFFFD; | ||
bytesNeeded = octets.length - i; | ||
} | ||
if (codePoint > 0xFFFF) { | ||
string += String.fromCharCode(0xD800 + ((codePoint - 0xFFFF - 1) >> 10)); | ||
string += String.fromCharCode(0xDC00 + ((codePoint - 0xFFFF - 1) & 0x3FF)); | ||
} else { | ||
string += String.fromCharCode(codePoint); | ||
} | ||
i += bytesNeeded + 1; | ||
} | ||
return string; | ||
}; | ||
if (TextDecoder == undefined) { | ||
TextDecoder = TextDecoderPolyfill; | ||
} | ||
var k = function () { | ||
@@ -193,3 +263,3 @@ }; | ||
if ("contentType" in xhr) { | ||
url += (url.indexOf("?", 0) === -1 ? "?" : "&") + "padding=true"; | ||
url += (url.indexOf("?") === -1 ? "?" : "&") + "padding=true"; | ||
} | ||
@@ -218,2 +288,5 @@ xhr.open(method, url, true); | ||
}; | ||
XHRWrapper.prototype.getAllResponseHeaders = function () { | ||
return this._xhr.getAllResponseHeaders != undefined ? this._xhr.getAllResponseHeaders() : ""; | ||
}; | ||
XHRWrapper.prototype.send = function () { | ||
@@ -246,8 +319,29 @@ // loading indicator in Safari < ? (6), Chrome < 14, Firefox | ||
function XHRTransport(xhr) { | ||
this._xhr = new XHRWrapper(xhr); | ||
function toLowerCase(name) { | ||
return name.replace(/[A-Z]/g, function (c) { | ||
return String.fromCharCode(c.charCodeAt(0) + 0x20); | ||
}); | ||
} | ||
XHRTransport.prototype.open = function (onStartCallback, onProgressCallback, onFinishCallback, url, withCredentials, headers) { | ||
var xhr = this._xhr; | ||
function HeadersPolyfill(all) { | ||
// Get headers: implemented according to mozilla's example code: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/getAllResponseHeaders#Example | ||
var map = Object.create(null); | ||
var array = all.split("\r\n"); | ||
for (var i = 0; i < array.length; i += 1) { | ||
var line = array[i]; | ||
var parts = line.split(": "); | ||
var name = parts.shift(); | ||
var value = parts.join(": "); | ||
map[toLowerCase(name)] = value; | ||
} | ||
this._map = map; | ||
} | ||
HeadersPolyfill.prototype.get = function (name) { | ||
return this._map[toLowerCase(name)]; | ||
}; | ||
function XHRTransport() { | ||
} | ||
XHRTransport.prototype.open = function (xhr, onStartCallback, onProgressCallback, onFinishCallback, url, withCredentials, headers) { | ||
xhr.open("GET", url); | ||
@@ -266,3 +360,6 @@ var offset = 0; | ||
var contentType = xhr.getResponseHeader("Content-Type"); | ||
onStartCallback(status, statusText, contentType); | ||
var headers = xhr.getAllResponseHeaders(); | ||
onStartCallback(status, statusText, contentType, new HeadersPolyfill(headers), function () { | ||
xhr.abort(); | ||
}); | ||
} else if (xhr.readyState === 4) { | ||
@@ -281,6 +378,45 @@ onFinishCallback(); | ||
}; | ||
function HeadersWrapper(headers) { | ||
this._headers = headers; | ||
} | ||
HeadersWrapper.prototype.get = function (name) { | ||
return this._headers.get(name); | ||
}; | ||
XHRTransport.prototype.cancel = function () { | ||
var xhr = this._xhr; | ||
xhr.abort(); | ||
function FetchTransport() { | ||
} | ||
FetchTransport.prototype.open = function (xhr, onStartCallback, onProgressCallback, onFinishCallback, url, withCredentials, headers) { | ||
// cache: "no-store" | ||
// https://bugs.chromium.org/p/chromium/issues/detail?id=453190 | ||
var textDecoder = new TextDecoder(); | ||
fetch(url, { | ||
headers: headers, | ||
credentials: withCredentials ? "include" : "same-origin" | ||
}).then(function (response) { | ||
var reader = response.body.getReader(); | ||
onStartCallback(response.status, response.statusText, response.headers.get("Content-Type"), new HeadersWrapper(response.headers), function () { | ||
reader.cancel(); | ||
}); | ||
return new Promise(function (resolve, reject) { | ||
var readNextChunk = function () { | ||
reader.read().then(function (result) { | ||
if (result.done) { | ||
//Note: bytes in textDecoder are ignored | ||
resolve(undefined); | ||
} else { | ||
var chunk = textDecoder.decode(result.value, {stream: true}); | ||
onProgressCallback(chunk); | ||
readNextChunk(); | ||
} | ||
})["catch"](function (error) { | ||
reject(error); | ||
}); | ||
}; | ||
readNextChunk(); | ||
}); | ||
})["finally"](function () { | ||
onFinishCallback(); | ||
}); | ||
}; | ||
@@ -367,2 +503,11 @@ | ||
function ConnectionEvent(type, options) { | ||
Event.call(this, type); | ||
this.status = options.status; | ||
this.statusText = options.statusText; | ||
this.headers = options.headers; | ||
} | ||
ConnectionEvent.prototype = Object.create(Event.prototype); | ||
var WAITING = -1; | ||
@@ -421,2 +566,10 @@ var CONNECTING = 0; | ||
function getBestTransport() { | ||
return XMLHttpRequest && "withCredentials" in XMLHttpRequest.prototype | ||
? XMLHttpRequest | ||
: XDomainRequest; | ||
} | ||
var isFetchSupported = fetch != undefined && Response != undefined && "body" in Response.prototype; | ||
function start(es, url, options) { | ||
@@ -427,3 +580,3 @@ url = String(url); | ||
var initialRetry = clampDuration(1000); | ||
var heartbeatTimeout = clampDuration(45000); | ||
var heartbeatTimeout = options != undefined && options.heartbeatTimeout != undefined ? parseDuration(options.heartbeatTimeout, 45000) : clampDuration(45000); | ||
@@ -434,4 +587,6 @@ var lastEventId = ""; | ||
var headers = options != undefined && options.headers != undefined ? JSON.parse(JSON.stringify(options.headers)) : undefined; | ||
var CurrentTransport = options != undefined && options.Transport != undefined ? options.Transport : (XDomainRequest != undefined ? XDomainRequest : XMLHttpRequest); | ||
var transport = new XHRTransport(new CurrentTransport()); | ||
var CurrentTransport = options != undefined && options.Transport != undefined ? options.Transport : getBestTransport(); | ||
var xhr = isFetchSupported ? undefined : new XHRWrapper(new CurrentTransport()); | ||
var transport = isFetchSupported ? new FetchTransport() : new XHRTransport(); | ||
var cancelFunction = undefined; | ||
var timeout = 0; | ||
@@ -448,4 +603,5 @@ var currentState = WAITING; | ||
var onStart = function (status, statusText, contentType) { | ||
var onStart = function (status, statusText, contentType, headers, cancel) { | ||
if (currentState === CONNECTING) { | ||
cancelFunction = cancel; | ||
if (status === 200 && contentType != undefined && contentTypeRegExp.test(contentType)) { | ||
@@ -456,3 +612,7 @@ currentState = OPEN; | ||
es.readyState = OPEN; | ||
var event = new Event("open"); | ||
var event = new ConnectionEvent("open", { | ||
status: status, | ||
statusText: statusText, | ||
headers: headers | ||
}); | ||
es.dispatchEvent(event); | ||
@@ -472,3 +632,7 @@ fire(es, es.onopen, event); | ||
close(); | ||
var event = new Event("error"); | ||
var event = new ConnectionEvent("error", { | ||
status: status, | ||
statusText: statusText, | ||
headers: headers | ||
}); | ||
es.dispatchEvent(event); | ||
@@ -591,3 +755,6 @@ fire(es, es.onerror, event); | ||
currentState = CLOSED; | ||
transport.cancel(); | ||
if (cancelFunction != undefined) { | ||
cancelFunction(); | ||
cancelFunction = undefined; | ||
} | ||
if (timeout !== 0) { | ||
@@ -604,5 +771,6 @@ clearTimeout(timeout); | ||
if (currentState !== WAITING) { | ||
if (!wasActivity) { | ||
if (!wasActivity && cancelFunction != undefined) { | ||
throwError(new Error("No activity within " + heartbeatTimeout + " milliseconds. Reconnecting.")); | ||
transport.cancel(); | ||
cancelFunction(); | ||
cancelFunction = undefined; | ||
} else { | ||
@@ -634,5 +802,6 @@ wasActivity = false; | ||
var requestURL = url; | ||
if (url.slice(0, 5) !== "data:" && | ||
url.slice(0, 5) !== "blob:") { | ||
requestURL = url + (url.indexOf("?", 0) === -1 ? "?" : "&") + "lastEventId=" + encodeURIComponent(lastEventId); | ||
if (url.slice(0, 5) !== "data:" && url.slice(0, 5) !== "blob:") { | ||
if (lastEventId !== "") { | ||
requestURL += (url.indexOf("?") === -1 ? "?" : "&") + "lastEventId=" + encodeURIComponent(lastEventId); | ||
} | ||
} | ||
@@ -649,3 +818,3 @@ var requestHeaders = {}; | ||
try { | ||
transport.open(onStart, onProgress, onFinish, requestURL, withCredentials, requestHeaders); | ||
transport.open(xhr, onStart, onProgress, onFinish, requestURL, withCredentials, requestHeaders); | ||
} catch (error) { | ||
@@ -652,0 +821,0 @@ close(); |
// 1. TextDecoder | ||
// 2. TextDecoder + stream option (Firefox 38 + - how to detect ?) | ||
// 1. TextDecoder - | ||
// 2. TextDecoder's stream option (Firefox 38 + - how to detect ?) - | ||
// 3. Promise.prototype.finally - | ||
// 4. fetch + | ||
// 5. Response.prototype.body + | ||
// 6. ReadableStream.prototype.getReader (no Firefox support yet) | ||
// 7. AbortController - (Firefox 57) | ||
// 6. ReadableStream.prototype.getReader (no Firefox support yet) + | ||
// 7. AbortController (Firefox 57) + | ||
@@ -110,4 +110,5 @@ var s = ""; | ||
if (Promise.prototype.finally == undefined) { | ||
Promise.prototype.finally = function (callback) { | ||
// ? | ||
if (Promise != undefined && Promise.prototype["finally"] == undefined) { | ||
Promise.prototype["finally"] = function (callback) { | ||
return this.then(function (result) { | ||
@@ -125,46 +126,36 @@ return Promise.resolve(callback()).then(function () { | ||
function FetchTransport() { | ||
//this.controller = undefined; | ||
this.reader = undefined; | ||
this.lastRequestId = 1; | ||
} | ||
FetchTransport.prototype.open = function (onStartCallback, onProgressCallback, onFinishCallback, url, withCredentials, headers) { | ||
var open = function (onStartCallback, onProgressCallback, onFinishCallback, url, withCredentials, headers, timeout) { | ||
// cache: "no-store" | ||
// https://bugs.chromium.org/p/chromium/issues/detail?id=453190 | ||
this.cancel(); | ||
var textDecoder = new TextDecoder(); | ||
var that = this; | ||
var lastRequestId = this.lastRequestId; | ||
this.controller = new AbortController(); | ||
fetch(url, { | ||
headers: headers, | ||
credentials: withCredentials ? "include" : "same-origin", | ||
signal: this.controller.signal | ||
credentials: withCredentials ? "include" : "same-origin" | ||
}).then(function (response) { | ||
if (lastRequestId === that.lastRequestId) { | ||
that.reader = response.body.getReader(); | ||
onStartCallback(response.status, response.statusText, response.headers.get("Content-Type")); | ||
return new Promise(function (resolve, reject) { | ||
var readNextChunk = function () { | ||
if (that.reader != undefined) { | ||
that.reader.read().then(function (result) { | ||
if (result.done) { | ||
//Note: bytes in textDecoder are ignored | ||
resolve(undefined); | ||
} else { | ||
var chunk = textDecoder.decode(result.value, {stream: true}); | ||
//var chunk = String.fromCharCode.apply(undefined, result.value); | ||
onProgressCallback(chunk); | ||
readNextChunk(); | ||
} | ||
})["catch"](reject); | ||
var reader = response.body.getReader(); | ||
onStartCallback(response.status, response.statusText, response.headers.get("Content-Type")); | ||
return new Promise(function (resolve, reject) { | ||
var readNextChunk = function () { | ||
var id = setTimeout(function () { | ||
reader.cancel(); | ||
resolve(undefined); | ||
}, timeout); | ||
reader.read().then(function (result) { | ||
clearTimeout(id); | ||
if (result.done) { | ||
//Note: bytes in textDecoder are ignored | ||
resolve(undefined); | ||
} else { | ||
resolve(undefined); | ||
var chunk = textDecoder.decode(result.value, {stream: true}); | ||
//var chunk = String.fromCharCode.apply(undefined, result.value); | ||
onProgressCallback(chunk); | ||
readNextChunk(); | ||
} | ||
}; | ||
readNextChunk(); | ||
}); | ||
} | ||
return undefined; | ||
})["catch"](function (error) { | ||
clearTimeout(id); | ||
reject(error); | ||
}); | ||
}; | ||
readNextChunk(); | ||
}); | ||
})["finally"](function () { | ||
@@ -175,98 +166,2 @@ onFinishCallback(); | ||
FetchTransport.prototype.cancel = function () { | ||
this.lastRequestId += 1; | ||
if (this.reader != undefined) { | ||
this.reader.cancel(); | ||
this.reader = undefined; | ||
} | ||
//if (this.controller != undefined) { | ||
// this.controller.abort(); | ||
//} | ||
}; | ||
function XHRTransport(xhr) { | ||
this.xhr = xhr; | ||
} | ||
XHRTransport.prototype.open = function (onStartCallback, onProgressCallback, onFinishCallback, url, withCredentials, headers) { | ||
var xhr = this.xhr; | ||
xhr.open("GET", url); | ||
var offset = 0; | ||
xhr.onprogress = function () { | ||
var responseText = xhr.responseText; | ||
var chunk = responseText.slice(offset); | ||
offset += chunk.length; | ||
onProgressCallback(chunk); | ||
}; | ||
xhr.onreadystatechange = function () { | ||
if (xhr.readyState === 2) { | ||
var status = xhr.status; | ||
var statusText = xhr.statusText; | ||
var contentType = xhr.getResponseHeader("Content-Type"); | ||
onStartCallback(status, statusText, contentType); | ||
} else if (xhr.readyState === 4) { | ||
onFinishCallback(); | ||
} | ||
}; | ||
xhr.withCredentials = withCredentials; | ||
xhr.responseType = "text"; | ||
for (var name in headers) { | ||
if (Object.prototype.hasOwnProperty.call(headers, name)) { | ||
xhr.setRequestHeader(name, headers[name]); | ||
} | ||
} | ||
xhr.send(); | ||
}; | ||
XHRTransport.prototype.cancel = function () { | ||
var xhr = this.xhr; | ||
xhr.abort(); | ||
}; | ||
function EventTarget() { | ||
this._listeners = new Map(); | ||
} | ||
function throwError(e) { | ||
setTimeout(function () { | ||
throw e; | ||
}, 0); | ||
} | ||
EventTarget.prototype.dispatchEvent = function (event) { | ||
event.target = this; | ||
var typeListeners = this._listeners.get(event.type); | ||
if (typeListeners != undefined) { | ||
typeListeners.forEach(function (listener) { | ||
try { | ||
if (typeof listener.handleEvent === "function") { | ||
listener.handleEvent(event); | ||
} else { | ||
listener.call(this, event); | ||
} | ||
} catch (e) { | ||
throwError(e); | ||
} | ||
}, this); | ||
} | ||
}; | ||
EventTarget.prototype.addEventListener = function (type, listener) { | ||
var listeners = this._listeners; | ||
var typeListeners = listeners.get(type); | ||
if (typeListeners == undefined) { | ||
typeListeners = new Set(); | ||
listeners.set(type, typeListeners); | ||
} | ||
typeListeners.add(listener); | ||
}; | ||
EventTarget.prototype.removeEventListener = function (type, listener) { | ||
var listeners = this._listeners; | ||
var typeListeners = listeners.get(type); | ||
if (typeListeners != undefined) { | ||
typeListeners["delete"](listener); | ||
if (typeListeners.size === 0) { | ||
listeners["delete"](type); | ||
} | ||
} | ||
}; |
@@ -80,2 +80,5 @@ var PORT1 = 8004; | ||
}); | ||
body = body.replace(/<bigData>/g, function () { | ||
return new Array(1024 * 1024 * 16).join("X"); | ||
}); | ||
body = body.split(/<delay\((\d+)\)>/); | ||
@@ -82,0 +85,0 @@ i = -1; |
@@ -233,2 +233,40 @@ /*jslint indent: 2, vars: true, plusplus: true */ | ||
asyncTest("onprogress-and-onreadystatechange-50ms", function () { | ||
var body = "data:1<delay(1000)>2<delay(25)>3<delay(25)>\n<delay(25)>\n"; | ||
var es = new EventSource(url + "?estest=" + encodeURIComponent(commonHeaders + "\n\n" + body)); | ||
es.onmessage = function (event) { | ||
es.close(); | ||
strictEqual(event.data, "123"); | ||
start(); | ||
}; | ||
es.onerror = function () { | ||
es.close(); | ||
ok(false, "no message event"); | ||
start(); | ||
}; | ||
}); | ||
// IE 11, Edge 17 | ||
asyncTest("fast-response-text-parsing-after-big-data", function () { | ||
var body = "<bigData>\n\n<delay(5000)>data: small1\n\n<delay(1000)>data: small2\n\n"; | ||
var es = new EventSource(url + "?estest=" + encodeURIComponent(commonHeaders + "\n\n" + body)); | ||
var t = 0; | ||
es.onmessage = function (event) { | ||
if (event.data === "small1") { | ||
t = Date.now(); | ||
} | ||
if (event.data === "small2") { | ||
t = Date.now() - t; | ||
es.close(); | ||
strictEqual(t < 1000 + 4, true); | ||
start(); | ||
} | ||
}; | ||
es.onerror = function () { | ||
es.close(); | ||
ok(false, "no message event"); | ||
start(); | ||
}; | ||
}); | ||
asyncTest("unicode", function () { | ||
@@ -235,0 +273,0 @@ var body = "data:<byte(F0)><delay(500)><byte(9F)><delay(500)><byte(8F)><delay(500)><byte(A9)><delay(500)>\n\n"; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
189938
4643
6