Advertisement
Guest User

Untitled

a guest
Mar 28th, 2013
566
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (function (global) {
  2.     "use strict";
  3.  
  4.     function Map() {
  5.         this.data = {}
  6.     }
  7.     function EventTarget() {
  8.         this.listeners = new Map
  9.     }
  10.     function throwError(e) {
  11.         setTimeout(function () {
  12.             throw e
  13.         }, 0)
  14.     }
  15.     function Event(type) {
  16.         this.type = type
  17.     }
  18.     function MessageEvent(type, options) {
  19.         Event.call(this, type), this.data = options.data, this.lastEventId = options.lastEventId
  20.     }
  21.     function getDuration(value, def) {
  22.         var n = Number(value);
  23.         return (n < 1 ? 1 : n > 18e6 ? 18e6 : n) || def
  24.     }
  25.     function fire(that, property, event) {
  26.         try {
  27.             typeof that[property] == "function" && that[property](event)
  28.         } catch (e) {
  29.             throwError(e)
  30.         }
  31.     }
  32.     function EventSource(url, options) {
  33.         function close() {
  34.             currentState = CLOSED, xhr !== null && (xhr.abort(), xhr = null), timeout !== 0 && (clearTimeout(timeout), timeout = 0), that.readyState = CLOSED
  35.         }
  36.         function onProgress(isLoadEnd) {
  37.             var responseText = currentState === OPEN || currentState === CONNECTING ? xhr.responseText || "" : "",
  38.                 event = null;
  39.             if (currentState === CONNECTING) {
  40.                 var contentType = isXHR ? responseText !== "" ? xhr.getResponseHeader("Content-Type") : "" : xhr.contentType;
  41.                 if (contentType && contentTypeRegExp.test(contentType)) {
  42.                     currentState = OPEN, wasActivity = !0, retry = initialRetry, that.readyState = OPEN, event = new Event("open"), that.dispatchEvent(event), fire(that, "onopen", event);
  43.                     if (currentState === CLOSED) return
  44.                 }
  45.             }
  46.             if (currentState === OPEN) {
  47.                 responseText.length > charOffset && (wasAct = !0, wasActivity = !0);
  48.                 var i = 0,
  49.                     i1 = responseText.indexOf("\r", charOffset),
  50.                     i2 = responseText.indexOf("\n", charOffset);
  51.                 while (i1 !== -1 || i2 !== -1) {
  52.                     i1 === -1 || i2 !== -1 && i2 < i1 ? (i = i2, i2 = responseText.indexOf("\n", i + 1)) : (i = i1, i1 = responseText.indexOf("\r", i + 1));
  53.                     var line = responseText.slice(charOffset, i),
  54.                         oldWasCR = wasCR;
  55.                     wasCR = responseText.slice(i, i + 1) === "\r", charOffset = i + 1;
  56.                     if (!oldWasCR || line.length !== 0 || wasCR) {
  57.                         responseBuffer.push(line);
  58.                         var field = responseBuffer.join("");
  59.                         responseBuffer.length = 0;
  60.                         if (field !== "") {
  61.                             var value = "",
  62.                                 j = field.indexOf(":", 0);
  63.                             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)))
  64.                         } else {
  65.                             if (dataBuffer.length !== 0) {
  66.                                 lastEventId = lastEventIdBuffer;
  67.                                 var type = eventTypeBuffer || "message";
  68.                                 event = new MessageEvent(type, {
  69.                                     data: dataBuffer.join("\n"),
  70.                                     lastEventId: lastEventIdBuffer
  71.                                 }), that.dispatchEvent(event), type === "message" && fire(that, "onmessage", event);
  72.                                 if (currentState === CLOSED) return
  73.                             }
  74.                             dataBuffer.length = 0, eventTypeBuffer = ""
  75.                         }
  76.                     }
  77.                 }
  78.                 charOffset !== responseText.length && (responseBuffer.push(responseText.slice(charOffset)), charOffset = responseText.length)
  79.             }
  80.             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))
  81.         }
  82.         function p() {
  83.             progressTimeout = 0, onProgress(!1)
  84.         }
  85.         function onProgress2() {
  86.             onProgress(!1)
  87.         }
  88.         function onLoadEnd() {
  89.             onProgress(!0)
  90.         }
  91.         function onTimeout() {
  92.             timeout = 0;
  93.             if (currentState !== WAITING) {
  94.                 onProgress(!1);
  95.                 return
  96.             }
  97.             if (navigator.onLine === !1) {
  98.                 timeout = setTimeout(onTimeout, 500);
  99.                 return
  100.             }
  101.             if (webkitBefore535 && global.document && (global.document.readyState === "loading" || global.document.readyState === "interactive")) {
  102.                 timeout = setTimeout(onTimeout, 100);
  103.                 return
  104.             }
  105.             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)
  106.         }
  107.         url = String(url);
  108.         var withCredentials = Boolean(xhr2 && options && options.withCredentials),
  109.             initialRetry = getDuration(options ? options.retry : NaN, 1e3),
  110.             retryLimit = getDuration(options ? options.retryLimit : NaN, 3e5),
  111.             heartbeatTimeout = getDuration(options ? options.heartbeatTimeout : NaN, 45e3),
  112.             lastEventId = options && options.lastEventId && String(options.lastEventId) || "",
  113.             that = this,
  114.             retry = initialRetry,
  115.             wasActivity = !1,
  116.             xhr = new Transport,
  117.             timeout = 0,
  118.             charOffset = 0,
  119.             currentState = WAITING,
  120.             dataBuffer = [],
  121.             lastEventIdBuffer = "",
  122.             eventTypeBuffer = "",
  123.             responseBuffer = [],
  124.             wasCR = !1,
  125.             progressTimeout = 0,
  126.             wasAct = !1;
  127.         options = null, EventTarget.call(this), this.close = close, this.url = url, this.readyState = CONNECTING, this.withCredentials = withCredentials, onTimeout()
  128.     }
  129.     function F() {
  130.         this.CONNECTING = CONNECTING, this.OPEN = OPEN, this.CLOSED = CLOSED
  131.     }
  132.     Map.prototype = {
  133.         get: function (key) {
  134.             return this.data[key + "~"]
  135.         },
  136.         set: function (key, value) {
  137.             this.data[key + "~"] = value
  138.         },
  139.         "delete": function (key) {
  140.             delete this.data[key + "~"]
  141.         }
  142.     }, EventTarget.prototype = {
  143.         dispatchEvent: function (event) {
  144.             var type = String(event.type),
  145.                 listeners = this.listeners,
  146.                 typeListeners = listeners.get(type);
  147.             if (!typeListeners) return;
  148.             var length = typeListeners.length,
  149.                 i = -1;
  150.             while (++i < length) {
  151.                 var listener = typeListeners[i];
  152.                 try {
  153.                     listener.call(this, event)
  154.                 } catch (e) {
  155.                     throwError(e)
  156.                 }
  157.             }
  158.         },
  159.         addEventListener: function (type, callback) {
  160.             type = String(type);
  161.             var listeners = this.listeners,
  162.                 typeListeners = listeners.get(type);
  163.             typeListeners || listeners.set(type, typeListeners = []);
  164.             var i = typeListeners.length;
  165.             while (--i >= 0) if (typeListeners[i] === callback) return;
  166.             typeListeners.push(callback)
  167.         },
  168.         removeEventListener: function (type, callback) {
  169.             type = String(type);
  170.             var listeners = this.listeners,
  171.                 typeListeners = listeners.get(type);
  172.             if (!typeListeners) return;
  173.             var length = typeListeners.length,
  174.                 filtered = [],
  175.                 i = -1;
  176.             while (++i < length) typeListeners[i] !== callback && filtered.push(typeListeners[i]);
  177.             filtered.length === 0 ? listeners["delete"](type) : listeners.set(type, filtered)
  178.         }
  179.     }, MessageEvent.prototype = Event.prototype;
  180.     var XHR = global.XMLHttpRequest,
  181.         XDR = global.XDomainRequest,
  182.         xhr2 = Boolean(XHR && (new XHR).withCredentials !== undefined),
  183.         isXHR = xhr2,
  184.         Transport = xhr2 ? XHR : XDR,
  185.         WAITING = -1,
  186.         CONNECTING = 0,
  187.         OPEN = 1,
  188.         CLOSED = 2,
  189.         contentTypeRegExp = /^text\/event\-stream;?(\s*charset\=utf\-8)?$/i,
  190.         webkitBefore535 = /AppleWebKit\/5([0-2][0-9]|3[0-4])[^\d]/.test(navigator.userAgent);
  191.     F.prototype = EventTarget.prototype, EventSource.prototype = new F, F.call(EventSource), Transport && (global.EventSource = EventSource)
  192.  })(this),
  193. function () {
  194.     function record(name) {
  195.         (new Image).src = "http://xkcd.com/events/" + name
  196.     }
  197.     function log() {
  198.         location.hash == "#verbose" && console.log.apply(console, arguments)
  199.     }
  200.     try {
  201.         var esURL = "http://c0.xkcd.com/stream/comic/time?method=EventSource",
  202.             source = new EventSource(esURL);
  203.         log("connecting to event source:", esURL), source.addEventListener("open", function (ev) {
  204.             record("connect_start")
  205.         }, !1), source.addEventListener("error", function (ev) {
  206.             record("connect_error")
  207.         }, !1), source.addEventListener("loadtest", log, !1), source.addEventListener("comic/time", log, !1), source.addEventListener("comic/time", function (ev) {
  208.             var data = JSON.parse(ev.data),
  209.                 img = document.getElementById("comic").getElementsByTagName("img")[0],
  210.                 delay = Math.round(Math.random() * data.spread);
  211.             log("waiting", delay, "seconds before displaying comic", data.image), setTimeout(function () {
  212.                 img.src = "http://imgs.xkcd.com/comics/time/" + data.image
  213.             }, delay * 1e3)
  214.         }, !1)
  215.     } catch (e) {
  216.         record("js_error")
  217.     }
  218. }();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement