Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (function (global) {
- "use strict";
- function Map() {
- this.data = {}
- }
- function EventTarget() {
- this.listeners = new Map
- }
- function throwError(e) {
- setTimeout(function () {
- throw e
- }, 0)
- }
- function Event(type) {
- this.type = type
- }
- function MessageEvent(type, options) {
- Event.call(this, type), this.data = options.data, this.lastEventId = options.lastEventId
- }
- function getDuration(value, def) {
- var n = Number(value);
- return (n < 1 ? 1 : n > 18e6 ? 18e6 : n) || def
- }
- function fire(that, property, event) {
- try {
- typeof that[property] == "function" && that[property](event)
- } catch (e) {
- throwError(e)
- }
- }
- function EventSource(url, options) {
- function close() {
- currentState = CLOSED, xhr !== null && (xhr.abort(), xhr = null), timeout !== 0 && (clearTimeout(timeout), timeout = 0), that.readyState = CLOSED
- }
- function onProgress(isLoadEnd) {
- var responseText = currentState === OPEN || currentState === CONNECTING ? xhr.responseText || "" : "",
- event = null;
- if (currentState === CONNECTING) {
- var contentType = isXHR ? responseText !== "" ? xhr.getResponseHeader("Content-Type") : "" : xhr.contentType;
- if (contentType && contentTypeRegExp.test(contentType)) {
- currentState = OPEN, wasActivity = !0, retry = initialRetry, that.readyState = OPEN, event = new Event("open"), that.dispatchEvent(event), fire(that, "onopen", event);
- if (currentState === CLOSED) return
- }
- }
- if (currentState === OPEN) {
- responseText.length > charOffset && (wasAct = !0, wasActivity = !0);
- var i = 0,
- i1 = responseText.indexOf("\r", charOffset),
- i2 = responseText.indexOf("\n", charOffset);
- while (i1 !== -1 || i2 !== -1) {
- i1 === -1 || i2 !== -1 && i2 < i1 ? (i = i2, i2 = responseText.indexOf("\n", i + 1)) : (i = i1, i1 = responseText.indexOf("\r", i + 1));
- var line = responseText.slice(charOffset, i),
- oldWasCR = wasCR;
- wasCR = responseText.slice(i, i + 1) === "\r", charOffset = i + 1;
- if (!oldWasCR || line.length !== 0 || wasCR) {
- responseBuffer.push(line);
- var field = responseBuffer.join("");
- responseBuffer.length = 0;
- if (field !== "") {
- var value = "",
- j = field.indexOf(":", 0);
- j !== -1 && (value = field.slice(j + (field.slice(j + 1, j + 2) === " " ? 2 : 1)), field = field.slice(0, j)), field === "data" ? dataBuffer.push(value) : field === "id" ? lastEventIdBuffer = value : field === "event" ? eventTypeBuffer = value : field === "retry" ? (initialRetry = getDuration(value, initialRetry), retry = initialRetry, retryLimit < initialRetry && (retryLimit = initialRetry)) : field === "retryLimit" ? retryLimit = getDuration(value, retryLimit) : field === "heartbeatTimeout" && (heartbeatTimeout = getDuration(value, heartbeatTimeout), timeout !== 0 && (clearTimeout(timeout), timeout = setTimeout(onTimeout, heartbeatTimeout)))
- } else {
- if (dataBuffer.length !== 0) {
- lastEventId = lastEventIdBuffer;
- var type = eventTypeBuffer || "message";
- event = new MessageEvent(type, {
- data: dataBuffer.join("\n"),
- lastEventId: lastEventIdBuffer
- }), that.dispatchEvent(event), type === "message" && fire(that, "onmessage", event);
- if (currentState === CLOSED) return
- }
- dataBuffer.length = 0, eventTypeBuffer = ""
- }
- }
- }
- charOffset !== responseText.length && (responseBuffer.push(responseText.slice(charOffset)), charOffset = responseText.length)
- }
- wasAct && progressTimeout === 0 && (wasAct = !1, progressTimeout = setTimeout(p, 80)), currentState !== OPEN && currentState !== CONNECTING || !(isLoadEnd || charOffset > 1048576 || timeout === 0 && !wasActivity) ? timeout === 0 && (wasActivity = !1, timeout = setTimeout(onTimeout, heartbeatTimeout)) : (currentState = WAITING, xhr.abort(), timeout !== 0 && (clearTimeout(timeout), timeout = 0), retry > retryLimit && (retry = retryLimit), timeout = setTimeout(onTimeout, retry), retry = retry * 2 + 1, that.readyState = CONNECTING, event = new Event("error"), that.dispatchEvent(event), fire(that, "onerror", event))
- }
- function p() {
- progressTimeout = 0, onProgress(!1)
- }
- function onProgress2() {
- onProgress(!1)
- }
- function onLoadEnd() {
- onProgress(!0)
- }
- function onTimeout() {
- timeout = 0;
- if (currentState !== WAITING) {
- onProgress(!1);
- return
- }
- if (navigator.onLine === !1) {
- timeout = setTimeout(onTimeout, 500);
- return
- }
- if (webkitBefore535 && global.document && (global.document.readyState === "loading" || global.document.readyState === "interactive")) {
- timeout = setTimeout(onTimeout, 100);
- return
- }
- xhr.onload = xhr.onerror = onLoadEnd, xhr.mozAnon === undefined ? xhr.onprogress = onProgress2 : xhr.onreadystatechange = onProgress2, wasActivity = !1, timeout = setTimeout(onTimeout, heartbeatTimeout), charOffset = 0, currentState = CONNECTING, dataBuffer.length = 0, eventTypeBuffer = "", lastEventIdBuffer = lastEventId, responseBuffer.length = 0, wasCR = !1, xhr.open("GET", url + ((url.indexOf("?", 0) === -1 ? "?" : "&") + "lastEventId=" + encodeURIComponent(lastEventId) + "&r=" + String(Math.random() + 1).slice(2)), !0), xhr.withCredentials = withCredentials, xhr.responseType = "text", isXHR && xhr.setRequestHeader("Accept", "text/event-stream"), xhr.send(null)
- }
- url = String(url);
- var withCredentials = Boolean(xhr2 && options && options.withCredentials),
- initialRetry = getDuration(options ? options.retry : NaN, 1e3),
- retryLimit = getDuration(options ? options.retryLimit : NaN, 3e5),
- heartbeatTimeout = getDuration(options ? options.heartbeatTimeout : NaN, 45e3),
- lastEventId = options && options.lastEventId && String(options.lastEventId) || "",
- that = this,
- retry = initialRetry,
- wasActivity = !1,
- xhr = new Transport,
- timeout = 0,
- charOffset = 0,
- currentState = WAITING,
- dataBuffer = [],
- lastEventIdBuffer = "",
- eventTypeBuffer = "",
- responseBuffer = [],
- wasCR = !1,
- progressTimeout = 0,
- wasAct = !1;
- options = null, EventTarget.call(this), this.close = close, this.url = url, this.readyState = CONNECTING, this.withCredentials = withCredentials, onTimeout()
- }
- function F() {
- this.CONNECTING = CONNECTING, this.OPEN = OPEN, this.CLOSED = CLOSED
- }
- Map.prototype = {
- get: function (key) {
- return this.data[key + "~"]
- },
- set: function (key, value) {
- this.data[key + "~"] = value
- },
- "delete": function (key) {
- delete this.data[key + "~"]
- }
- }, EventTarget.prototype = {
- dispatchEvent: function (event) {
- var type = String(event.type),
- listeners = this.listeners,
- typeListeners = listeners.get(type);
- if (!typeListeners) return;
- var length = typeListeners.length,
- i = -1;
- while (++i < length) {
- var listener = typeListeners[i];
- try {
- listener.call(this, event)
- } catch (e) {
- throwError(e)
- }
- }
- },
- addEventListener: function (type, callback) {
- type = String(type);
- var listeners = this.listeners,
- typeListeners = listeners.get(type);
- typeListeners || listeners.set(type, typeListeners = []);
- var i = typeListeners.length;
- while (--i >= 0) if (typeListeners[i] === callback) return;
- typeListeners.push(callback)
- },
- removeEventListener: function (type, callback) {
- type = String(type);
- var listeners = this.listeners,
- typeListeners = listeners.get(type);
- if (!typeListeners) return;
- var length = typeListeners.length,
- filtered = [],
- i = -1;
- while (++i < length) typeListeners[i] !== callback && filtered.push(typeListeners[i]);
- filtered.length === 0 ? listeners["delete"](type) : listeners.set(type, filtered)
- }
- }, MessageEvent.prototype = Event.prototype;
- var XHR = global.XMLHttpRequest,
- XDR = global.XDomainRequest,
- xhr2 = Boolean(XHR && (new XHR).withCredentials !== undefined),
- isXHR = xhr2,
- Transport = xhr2 ? XHR : XDR,
- WAITING = -1,
- CONNECTING = 0,
- OPEN = 1,
- CLOSED = 2,
- contentTypeRegExp = /^text\/event\-stream;?(\s*charset\=utf\-8)?$/i,
- webkitBefore535 = /AppleWebKit\/5([0-2][0-9]|3[0-4])[^\d]/.test(navigator.userAgent);
- F.prototype = EventTarget.prototype, EventSource.prototype = new F, F.call(EventSource), Transport && (global.EventSource = EventSource)
- })(this),
- function () {
- function record(name) {
- (new Image).src = "http://xkcd.com/events/" + name
- }
- function log() {
- location.hash == "#verbose" && console.log.apply(console, arguments)
- }
- try {
- var esURL = "http://c0.xkcd.com/stream/comic/time?method=EventSource",
- source = new EventSource(esURL);
- log("connecting to event source:", esURL), source.addEventListener("open", function (ev) {
- record("connect_start")
- }, !1), source.addEventListener("error", function (ev) {
- record("connect_error")
- }, !1), source.addEventListener("loadtest", log, !1), source.addEventListener("comic/time", log, !1), source.addEventListener("comic/time", function (ev) {
- var data = JSON.parse(ev.data),
- img = document.getElementById("comic").getElementsByTagName("img")[0],
- delay = Math.round(Math.random() * data.spread);
- log("waiting", delay, "seconds before displaying comic", data.image), setTimeout(function () {
- img.src = "http://imgs.xkcd.com/comics/time/" + data.image
- }, delay * 1e3)
- }, !1)
- } catch (e) {
- record("js_error")
- }
- }();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement