polyfills.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  1. /**
  2. * polyfills.js — IE11 / 老浏览器兼容垫片
  3. * ES5 语法,离线内置,无外部依赖。
  4. *
  5. * 提供:
  6. * String: padStart / startsWith / endsWith / includes
  7. * Array: includes
  8. * Object: assign
  9. * Promise: then / catch / finally / all / race / resolve / reject
  10. * fetch: 基于 XMLHttpRequest
  11. * EventSource: 基于 XMLHttpRequest,支持 SSE 消息解析和断线重连
  12. *
  13. * 注意:
  14. * 1. 本文件应在业务 JS 之前加载。
  15. * 2. fetch 和 EventSource 是兼容实现,不保证与原生 API 完全一致。
  16. * 3. downloadBlobFile() 保留在 util.js,不放在这里。
  17. */
  18. (function (global) {
  19. "use strict";
  20. /* =========================================================
  21. * String / Array / Object
  22. * ========================================================= */
  23. if (!String.prototype.padStart) {
  24. String.prototype.padStart = function (targetLength, padString) {
  25. var str = String(this);
  26. var len = Number(targetLength) || 0;
  27. var pad = padString === undefined ? " " : String(padString);
  28. var need = len - str.length;
  29. var result = "";
  30. if (need <= 0) return str;
  31. if (pad === "") return str;
  32. while (result.length < need) {
  33. result += pad;
  34. }
  35. return result.slice(0, need) + str;
  36. };
  37. }
  38. if (!String.prototype.startsWith) {
  39. String.prototype.startsWith = function (search, position) {
  40. var str = String(this);
  41. var pos = Number(position) || 0;
  42. search = String(search);
  43. if (pos < 0) pos = 0;
  44. return str.substr(pos, search.length) === search;
  45. };
  46. }
  47. if (!String.prototype.endsWith) {
  48. String.prototype.endsWith = function (search, length) {
  49. var str = String(this);
  50. search = String(search);
  51. if (length === undefined || length > str.length) {
  52. length = str.length;
  53. }
  54. length = Number(length);
  55. if (isNaN(length) || length < 0) length = 0;
  56. return str.substring(length - search.length, length) === search;
  57. };
  58. }
  59. if (!String.prototype.includes) {
  60. String.prototype.includes = function (search, start) {
  61. if (search instanceof RegExp) {
  62. throw new TypeError("不支持将 RegExp 作为 includes 参数");
  63. }
  64. return String(this).indexOf(String(search), Number(start) || 0) !== -1;
  65. };
  66. }
  67. if (!Array.prototype.includes) {
  68. Array.prototype.includes = function (search, fromIndex) {
  69. var arr = Object(this);
  70. var len = arr.length >>> 0;
  71. var i = Number(fromIndex) || 0;
  72. if (!len) return false;
  73. if (i < 0) {
  74. i = Math.max(len + i, 0);
  75. }
  76. for (; i < len; i++) {
  77. if (arr[i] === search ||
  78. (arr[i] !== arr[i] && search !== search)) {
  79. return true;
  80. }
  81. }
  82. return false;
  83. };
  84. }
  85. if (!Object.assign) {
  86. Object.assign = function (target) {
  87. if (target == null) {
  88. throw new TypeError("Object.assign 的目标不能为 null 或 undefined");
  89. }
  90. var to = Object(target);
  91. var i;
  92. var source;
  93. var key;
  94. for (i = 1; i < arguments.length; i++) {
  95. source = arguments[i];
  96. if (source == null) continue;
  97. source = Object(source);
  98. for (key in source) {
  99. if (Object.prototype.hasOwnProperty.call(source, key)) {
  100. to[key] = source[key];
  101. }
  102. }
  103. }
  104. return to;
  105. };
  106. }
  107. /* =========================================================
  108. * Promise
  109. * ========================================================= */
  110. if (!global.Promise) {
  111. var PENDING = 0;
  112. var FULFILLED = 1;
  113. var REJECTED = 2;
  114. function flushLater(fn) {
  115. setTimeout(fn, 0);
  116. }
  117. function isObjectOrFunction(value) {
  118. return value !== null &&
  119. (typeof value === "object" || typeof value === "function");
  120. }
  121. function settle(promise, state, value) {
  122. if (promise._state !== PENDING) return;
  123. if (state === FULFILLED && value === promise) {
  124. settle(promise, REJECTED, new TypeError("Promise 不能解决为自身"));
  125. return;
  126. }
  127. if (state === FULFILLED && isObjectOrFunction(value)) {
  128. var then;
  129. var called = false;
  130. try {
  131. then = value.then;
  132. } catch (err) {
  133. settle(promise, REJECTED, err);
  134. return;
  135. }
  136. if (typeof then === "function") {
  137. try {
  138. then.call(
  139. value,
  140. function (result) {
  141. if (called) return;
  142. called = true;
  143. settle(promise, FULFILLED, result);
  144. },
  145. function (reason) {
  146. if (called) return;
  147. called = true;
  148. settle(promise, REJECTED, reason);
  149. }
  150. );
  151. } catch (err2) {
  152. if (!called) {
  153. called = true;
  154. settle(promise, REJECTED, err2);
  155. }
  156. }
  157. return;
  158. }
  159. }
  160. promise._state = state;
  161. promise._value = value;
  162. if (promise._handlers.length) {
  163. flushLater(function () {
  164. flushHandlers(promise);
  165. });
  166. }
  167. }
  168. function flushHandlers(promise) {
  169. var handlers = promise._handlers.slice();
  170. var i;
  171. var handler;
  172. var callback;
  173. var result;
  174. promise._handlers = [];
  175. for (i = 0; i < handlers.length; i++) {
  176. handler = handlers[i];
  177. callback = promise._state === FULFILLED
  178. ? handler.onFulfilled
  179. : handler.onRejected;
  180. if (typeof callback !== "function") {
  181. if (promise._state === FULFILLED) {
  182. settle(handler.next, FULFILLED, promise._value);
  183. } else {
  184. settle(handler.next, REJECTED, promise._value);
  185. }
  186. continue;
  187. }
  188. try {
  189. result = callback(promise._value);
  190. settle(handler.next, FULFILLED, result);
  191. } catch (err) {
  192. settle(handler.next, REJECTED, err);
  193. }
  194. }
  195. }
  196. function PromisePolyfill(executor) {
  197. if (!(this instanceof PromisePolyfill)) {
  198. throw new TypeError("Promise 必须通过 new 调用");
  199. }
  200. if (typeof executor !== "function") {
  201. throw new TypeError("Promise executor 必须是函数");
  202. }
  203. this._state = PENDING;
  204. this._value = undefined;
  205. this._handlers = [];
  206. var self = this;
  207. var done = false;
  208. function resolve(value) {
  209. if (done) return;
  210. done = true;
  211. settle(self, FULFILLED, value);
  212. }
  213. function reject(reason) {
  214. if (done) return;
  215. done = true;
  216. settle(self, REJECTED, reason);
  217. }
  218. try {
  219. executor(resolve, reject);
  220. } catch (err) {
  221. reject(err);
  222. }
  223. }
  224. PromisePolyfill.prototype.then = function (onFulfilled, onRejected) {
  225. var next = new PromisePolyfill(function () {});
  226. this._handlers.push({
  227. onFulfilled: onFulfilled,
  228. onRejected: onRejected,
  229. next: next
  230. });
  231. if (this._state !== PENDING) {
  232. var self = this;
  233. flushLater(function () {
  234. flushHandlers(self);
  235. });
  236. }
  237. return next;
  238. };
  239. PromisePolyfill.prototype["catch"] = function (onRejected) {
  240. return this.then(null, onRejected);
  241. };
  242. PromisePolyfill.prototype["finally"] = function (callback) {
  243. var P = this.constructor || PromisePolyfill;
  244. if (typeof callback !== "function") {
  245. return this.then(callback, callback);
  246. }
  247. return this.then(
  248. function (value) {
  249. return P.resolve(callback()).then(function () {
  250. return value;
  251. });
  252. },
  253. function (reason) {
  254. return P.resolve(callback()).then(function () {
  255. throw reason;
  256. });
  257. }
  258. );
  259. };
  260. PromisePolyfill.resolve = function (value) {
  261. if (value instanceof PromisePolyfill) return value;
  262. return new PromisePolyfill(function (resolve) {
  263. resolve(value);
  264. });
  265. };
  266. PromisePolyfill.reject = function (reason) {
  267. return new PromisePolyfill(function (resolve, reject) {
  268. reject(reason);
  269. });
  270. };
  271. PromisePolyfill.all = function (items) {
  272. return new PromisePolyfill(function (resolve, reject) {
  273. var list;
  274. var results = [];
  275. var remaining;
  276. var i;
  277. try {
  278. list = Array.prototype.slice.call(items);
  279. } catch (err) {
  280. reject(err);
  281. return;
  282. }
  283. if (!list.length) {
  284. resolve([]);
  285. return;
  286. }
  287. remaining = list.length;
  288. function makeResolver(index) {
  289. return function (value) {
  290. results[index] = value;
  291. remaining--;
  292. if (remaining === 0) {
  293. resolve(results);
  294. }
  295. };
  296. }
  297. for (i = 0; i < list.length; i++) {
  298. PromisePolyfill.resolve(list[i]).then(
  299. makeResolver(i),
  300. reject
  301. );
  302. }
  303. });
  304. };
  305. PromisePolyfill.race = function (items) {
  306. return new PromisePolyfill(function (resolve, reject) {
  307. var list;
  308. var i;
  309. try {
  310. list = Array.prototype.slice.call(items);
  311. } catch (err) {
  312. reject(err);
  313. return;
  314. }
  315. for (i = 0; i < list.length; i++) {
  316. PromisePolyfill.resolve(list[i]).then(resolve, reject);
  317. }
  318. });
  319. };
  320. global.Promise = PromisePolyfill;
  321. }
  322. /* =========================================================
  323. * fetch — 基于 XMLHttpRequest
  324. * ========================================================= */
  325. if (!global.fetch && global.XMLHttpRequest) {
  326. function HeadersPolyfill(headers) {
  327. this._headers = {};
  328. var key;
  329. var value;
  330. var i;
  331. if (!headers) return;
  332. if (typeof headers.forEach === "function") {
  333. var self = this;
  334. headers.forEach(function (v, k) {
  335. self.append(k, v);
  336. });
  337. } else if (Object.prototype.toString.call(headers) === "[object Array]") {
  338. for (i = 0; i < headers.length; i++) {
  339. if (headers[i] && headers[i].length >= 2) {
  340. this.append(headers[i][0], headers[i][1]);
  341. }
  342. }
  343. } else {
  344. for (key in headers) {
  345. if (Object.prototype.hasOwnProperty.call(headers, key)) {
  346. value = headers[key];
  347. this.append(key, value);
  348. }
  349. }
  350. }
  351. }
  352. HeadersPolyfill.prototype.append = function (name, value) {
  353. name = String(name).toLowerCase();
  354. value = String(value);
  355. if (this._headers[name]) {
  356. this._headers[name] += ", " + value;
  357. } else {
  358. this._headers[name] = value;
  359. }
  360. };
  361. HeadersPolyfill.prototype.set = function (name, value) {
  362. this._headers[String(name).toLowerCase()] = String(value);
  363. };
  364. HeadersPolyfill.prototype.get = function (name) {
  365. var value = this._headers[String(name).toLowerCase()];
  366. return value === undefined ? null : value;
  367. };
  368. HeadersPolyfill.prototype.has = function (name) {
  369. return Object.prototype.hasOwnProperty.call(
  370. this._headers,
  371. String(name).toLowerCase()
  372. );
  373. };
  374. HeadersPolyfill.prototype["delete"] = function (name) {
  375. delete this._headers[String(name).toLowerCase()];
  376. };
  377. HeadersPolyfill.prototype.forEach = function (callback, thisArg) {
  378. var key;
  379. for (key in this._headers) {
  380. if (Object.prototype.hasOwnProperty.call(this._headers, key)) {
  381. callback.call(thisArg, this._headers[key], key, this);
  382. }
  383. }
  384. };
  385. function parseResponseHeaders(raw) {
  386. var headers = new HeadersPolyfill();
  387. var lines = raw ? raw.split(/\r?\n/) : [];
  388. var i;
  389. var index;
  390. for (i = 0; i < lines.length; i++) {
  391. index = lines[i].indexOf(":");
  392. if (index > 0) {
  393. headers.append(
  394. lines[i].substring(0, index).replace(/^\s+|\s+$/g, ""),
  395. lines[i].substring(index + 1).replace(/^\s+|\s+$/g, "")
  396. );
  397. }
  398. }
  399. return headers;
  400. }
  401. function ResponsePolyfill(xhr) {
  402. this.status = xhr.status === 1223 ? 204 : xhr.status;
  403. this.statusText = xhr.statusText || "";
  404. this.ok = this.status >= 200 && this.status < 300;
  405. this.url = xhr.responseURL || "";
  406. this.headers = parseResponseHeaders(xhr.getAllResponseHeaders());
  407. this._xhr = xhr;
  408. this._bodyUsed = false;
  409. }
  410. ResponsePolyfill.prototype.text = function () {
  411. var xhr = this._xhr;
  412. return Promise.resolve(xhr.responseText || "");
  413. };
  414. ResponsePolyfill.prototype.json = function () {
  415. return this.text().then(function (text) {
  416. return JSON.parse(text);
  417. });
  418. };
  419. ResponsePolyfill.prototype.blob = function () {
  420. var xhr = this._xhr;
  421. if (xhr.response && typeof xhr.response !== "string") {
  422. return Promise.resolve(xhr.response);
  423. }
  424. if (global.Blob) {
  425. return Promise.resolve(new Blob([xhr.responseText || ""], {
  426. type: this.headers.get("content-type") || ""
  427. }));
  428. }
  429. return Promise.reject(new Error("当前浏览器不支持 Blob"));
  430. };
  431. ResponsePolyfill.prototype.clone = function () {
  432. return new ResponsePolyfill(this._xhr);
  433. };
  434. global.Headers = global.Headers || HeadersPolyfill;
  435. global.Response = global.Response || ResponsePolyfill;
  436. global.fetch = function (input, init) {
  437. return new Promise(function (resolve, reject) {
  438. var options = init || {};
  439. var url = typeof input === "string" ? input : input.url;
  440. var method = options.method || "GET";
  441. var xhr = new XMLHttpRequest();
  442. var headers = new HeadersPolyfill(options.headers);
  443. var body = options.body === undefined ? null : options.body;
  444. var key;
  445. var settled = false;
  446. function fail(err) {
  447. if (settled) return;
  448. settled = true;
  449. reject(err);
  450. }
  451. try {
  452. xhr.open(method, url, true);
  453. if (options.credentials === "include") {
  454. xhr.withCredentials = true;
  455. } else if (options.credentials === "same-origin") {
  456. xhr.withCredentials = false;
  457. }
  458. if (options.responseType && options.responseType !== "text") {
  459. try {
  460. xhr.responseType = options.responseType;
  461. } catch (ignore) {}
  462. }
  463. headers.forEach(function (value, name) {
  464. xhr.setRequestHeader(name, value);
  465. });
  466. xhr.onload = function () {
  467. if (settled) return;
  468. settled = true;
  469. if (xhr.status === 0) {
  470. reject(new TypeError("网络请求失败"));
  471. return;
  472. }
  473. resolve(new ResponsePolyfill(xhr));
  474. };
  475. xhr.onerror = function () {
  476. fail(new TypeError("网络请求失败"));
  477. };
  478. xhr.ontimeout = function () {
  479. fail(new TypeError("网络请求超时"));
  480. };
  481. xhr.onabort = function () {
  482. fail(new TypeError("网络请求已取消"));
  483. };
  484. if (options.timeout) {
  485. xhr.timeout = options.timeout;
  486. }
  487. xhr.send(body);
  488. } catch (err) {
  489. fail(err);
  490. }
  491. });
  492. };
  493. }
  494. /* =========================================================
  495. * EventSource — 基于 XMLHttpRequest 的 SSE 兼容实现
  496. * ========================================================= */
  497. if (!global.EventSource && global.XMLHttpRequest) {
  498. function EventSourcePolyfill(url, options) {
  499. if (!(this instanceof EventSourcePolyfill)) {
  500. throw new TypeError("EventSource 必须通过 new 调用");
  501. }
  502. if (!url) {
  503. throw new TypeError("EventSource URL 不能为空");
  504. }
  505. this.url = String(url);
  506. this.withCredentials = !!(options && options.withCredentials);
  507. this.CONNECTING = 0;
  508. this.OPEN = 1;
  509. this.CLOSED = 2;
  510. this.readyState = this.CONNECTING;
  511. this.onopen = null;
  512. this.onmessage = null;
  513. this.onerror = null;
  514. this._xhr = null;
  515. this._timer = null;
  516. this._closed = false;
  517. this._retry = 3000;
  518. this._lastEventId = "";
  519. this._buffer = "";
  520. this._listeners = {};
  521. this._connect();
  522. }
  523. EventSourcePolyfill.prototype.addEventListener = function (type, listener) {
  524. if (typeof listener !== "function") return;
  525. if (!this._listeners[type]) {
  526. this._listeners[type] = [];
  527. }
  528. this._listeners[type].push(listener);
  529. };
  530. EventSourcePolyfill.prototype.removeEventListener = function (type, listener) {
  531. var list = this._listeners[type];
  532. var i;
  533. if (!list) return;
  534. for (i = list.length - 1; i >= 0; i--) {
  535. if (list[i] === listener) {
  536. list.splice(i, 1);
  537. }
  538. }
  539. };
  540. EventSourcePolyfill.prototype.dispatchEvent = function (event) {
  541. var list = this._listeners[event.type] || [];
  542. var i;
  543. if (typeof this["on" + event.type] === "function") {
  544. try {
  545. this["on" + event.type].call(this, event);
  546. } catch (ignore) {}
  547. }
  548. list = list.slice();
  549. for (i = 0; i < list.length; i++) {
  550. try {
  551. list[i].call(this, event);
  552. } catch (ignore2) {}
  553. }
  554. return true;
  555. };
  556. EventSourcePolyfill.prototype._emit = function (type, data, lastEventId) {
  557. var event = {
  558. type: type,
  559. data: data === undefined ? "" : data,
  560. lastEventId: lastEventId || "",
  561. origin: "",
  562. target: this
  563. };
  564. event.preventDefault = function () {};
  565. event.stopPropagation = function () {};
  566. this.dispatchEvent(event);
  567. };
  568. EventSourcePolyfill.prototype._connect = function () {
  569. var self = this;
  570. var xhr;
  571. var lastLength = 0;
  572. var finished = false;
  573. if (this._closed) return;
  574. try {
  575. xhr = new XMLHttpRequest();
  576. this._xhr = xhr;
  577. this._buffer = "";
  578. xhr.open("GET", this.url, true);
  579. xhr.setRequestHeader("Accept", "text/event-stream");
  580. xhr.setRequestHeader("Cache-Control", "no-cache");
  581. if (this._lastEventId) {
  582. xhr.setRequestHeader("Last-Event-ID", this._lastEventId);
  583. }
  584. xhr.withCredentials = this.withCredentials;
  585. function readData() {
  586. var text;
  587. var chunk;
  588. try {
  589. text = xhr.responseText || "";
  590. } catch (ignore) {
  591. return;
  592. }
  593. if (text.length < lastLength) {
  594. lastLength = 0;
  595. self._buffer = "";
  596. }
  597. if (text.length <= lastLength) return;
  598. chunk = text.substring(lastLength);
  599. lastLength = text.length;
  600. self._buffer += chunk;
  601. self._parseBuffer(false);
  602. }
  603. xhr.onreadystatechange = function () {
  604. if (self._closed || finished) return;
  605. if (xhr.readyState === 2 || xhr.readyState === 3) {
  606. if (xhr.status >= 200 && xhr.status < 300) {
  607. if (self.readyState !== self.OPEN) {
  608. self.readyState = self.OPEN;
  609. self._emit("open");
  610. }
  611. if (xhr.readyState === 3) {
  612. readData();
  613. }
  614. } else if (xhr.readyState === 2) {
  615. finished = true;
  616. self._handleError();
  617. }
  618. }
  619. if (xhr.readyState === 4) {
  620. readData();
  621. if (!self._closed) {
  622. finished = true;
  623. self._parseBuffer(true);
  624. self._handleError();
  625. }
  626. }
  627. };
  628. xhr.onerror = function () {
  629. if (self._closed || finished) return;
  630. finished = true;
  631. self._handleError();
  632. };
  633. xhr.ontimeout = function () {
  634. if (self._closed || finished) return;
  635. finished = true;
  636. self._handleError();
  637. };
  638. xhr.send(null);
  639. } catch (err) {
  640. this._handleError();
  641. }
  642. };
  643. EventSourcePolyfill.prototype._parseBuffer = function (flush) {
  644. var index;
  645. var line;
  646. var fields;
  647. var i;
  648. var field;
  649. var value;
  650. var data = [];
  651. var eventType = "";
  652. var eventId = this._lastEventId;
  653. var retry = null;
  654. while ((index = this._buffer.indexOf("\n")) !== -1) {
  655. line = this._buffer.substring(0, index);
  656. this._buffer = this._buffer.substring(index + 1);
  657. if (line.charAt(line.length - 1) === "\r") {
  658. line = line.substring(0, line.length - 1);
  659. }
  660. if (line === "") {
  661. if (data.length) {
  662. this._lastEventId = eventId;
  663. this._emit(
  664. eventType || "message",
  665. data.join("\n"),
  666. eventId
  667. );
  668. }
  669. data = [];
  670. eventType = "";
  671. eventId = this._lastEventId;
  672. continue;
  673. }
  674. if (line.charAt(0) === ":") continue;
  675. fields = line.split(":");
  676. field = fields.shift();
  677. value = fields.join(":");
  678. if (value.charAt(0) === " ") {
  679. value = value.substring(1);
  680. }
  681. if (field === "data") {
  682. data.push(value);
  683. } else if (field === "event") {
  684. eventType = value;
  685. } else if (field === "id" && value.indexOf("\0") === -1) {
  686. eventId = value;
  687. } else if (field === "retry") {
  688. if (/^\d+$/.test(value)) {
  689. retry = parseInt(value, 10);
  690. }
  691. }
  692. }
  693. if (retry !== null && retry >= 0) {
  694. this._retry = retry;
  695. }
  696. if (flush && this._buffer) {
  697. line = this._buffer;
  698. this._buffer = "";
  699. if (line.charAt(line.length - 1) === "\r") {
  700. line = line.substring(0, line.length - 1);
  701. }
  702. if (line.indexOf(":") !== 0) {
  703. fields = line.split(":");
  704. field = fields.shift();
  705. value = fields.join(":");
  706. if (value.charAt(0) === " ") {
  707. value = value.substring(1);
  708. }
  709. if (field === "data") {
  710. data.push(value);
  711. } else if (field === "event") {
  712. eventType = value;
  713. } else if (field === "id" && value.indexOf("\0") === -1) {
  714. eventId = value;
  715. } else if (field === "retry" && /^\d+$/.test(value)) {
  716. this._retry = parseInt(value, 10);
  717. }
  718. }
  719. if (data.length) {
  720. this._lastEventId = eventId;
  721. this._emit(
  722. eventType || "message",
  723. data.join("\n"),
  724. eventId
  725. );
  726. }
  727. }
  728. };
  729. EventSourcePolyfill.prototype._handleError = function () {
  730. var self = this;
  731. if (this._closed) return;
  732. this.readyState = this.CONNECTING;
  733. this._emit("error");
  734. if (this._timer) {
  735. clearTimeout(this._timer);
  736. }
  737. this._timer = setTimeout(function () {
  738. self._timer = null;
  739. self._connect();
  740. }, this._retry);
  741. };
  742. EventSourcePolyfill.prototype.close = function () {
  743. this._closed = true;
  744. this.readyState = this.CLOSED;
  745. if (this._timer) {
  746. clearTimeout(this._timer);
  747. this._timer = null;
  748. }
  749. if (this._xhr) {
  750. try {
  751. this._xhr.onreadystatechange = null;
  752. this._xhr.onerror = null;
  753. this._xhr.abort();
  754. } catch (ignore) {}
  755. this._xhr = null;
  756. }
  757. };
  758. global.EventSource = EventSourcePolyfill;
  759. }
  760. })(window);