Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

polling-jsonp.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /**
  2. * Module requirements.
  3. */
  4. var Polling = require('./polling');
  5. var inherit = require('component-inherit');
  6. /**
  7. * Module exports.
  8. */
  9. module.exports = JSONPPolling;
  10. /**
  11. * Cached regular expressions.
  12. */
  13. var rNewline = /\n/g;
  14. var rEscapedNewline = /\\n/g;
  15. /**
  16. * Global JSONP callbacks.
  17. */
  18. var callbacks;
  19. /**
  20. * Noop.
  21. */
  22. function empty () { }
  23. /**
  24. * Until https://github.com/tc39/proposal-global is shipped.
  25. */
  26. function glob () {
  27. return typeof self !== 'undefined' ? self
  28. : typeof window !== 'undefined' ? window
  29. : typeof global !== 'undefined' ? global : {};
  30. }
  31. /**
  32. * JSONP Polling constructor.
  33. *
  34. * @param {Object} opts.
  35. * @api public
  36. */
  37. function JSONPPolling (opts) {
  38. Polling.call(this, opts);
  39. this.query = this.query || {};
  40. // define global callbacks array if not present
  41. // we do this here (lazily) to avoid unneeded global pollution
  42. if (!callbacks) {
  43. // we need to consider multiple engines in the same page
  44. var global = glob();
  45. callbacks = global.___eio = (global.___eio || []);
  46. }
  47. // callback identifier
  48. this.index = callbacks.length;
  49. // add callback to jsonp global
  50. var self = this;
  51. callbacks.push(function (msg) {
  52. self.onData(msg);
  53. });
  54. // append to query string
  55. this.query.j = this.index;
  56. // prevent spurious errors from being emitted when the window is unloaded
  57. if (typeof addEventListener === 'function') {
  58. addEventListener('beforeunload', function () {
  59. if (self.script) self.script.onerror = empty;
  60. }, false);
  61. }
  62. }
  63. /**
  64. * Inherits from Polling.
  65. */
  66. inherit(JSONPPolling, Polling);
  67. /*
  68. * JSONP only supports binary as base64 encoded strings
  69. */
  70. JSONPPolling.prototype.supportsBinary = false;
  71. /**
  72. * Closes the socket.
  73. *
  74. * @api private
  75. */
  76. JSONPPolling.prototype.doClose = function () {
  77. if (this.script) {
  78. this.script.parentNode.removeChild(this.script);
  79. this.script = null;
  80. }
  81. if (this.form) {
  82. this.form.parentNode.removeChild(this.form);
  83. this.form = null;
  84. this.iframe = null;
  85. }
  86. Polling.prototype.doClose.call(this);
  87. };
  88. /**
  89. * Starts a poll cycle.
  90. *
  91. * @api private
  92. */
  93. JSONPPolling.prototype.doPoll = function () {
  94. var self = this;
  95. var script = document.createElement('script');
  96. if (this.script) {
  97. this.script.parentNode.removeChild(this.script);
  98. this.script = null;
  99. }
  100. script.async = true;
  101. script.src = this.uri();
  102. script.onerror = function (e) {
  103. self.onError('jsonp poll error', e);
  104. };
  105. var insertAt = document.getElementsByTagName('script')[0];
  106. if (insertAt) {
  107. insertAt.parentNode.insertBefore(script, insertAt);
  108. } else {
  109. (document.head || document.body).appendChild(script);
  110. }
  111. this.script = script;
  112. var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent);
  113. if (isUAgecko) {
  114. setTimeout(function () {
  115. var iframe = document.createElement('iframe');
  116. document.body.appendChild(iframe);
  117. document.body.removeChild(iframe);
  118. }, 100);
  119. }
  120. };
  121. /**
  122. * Writes with a hidden iframe.
  123. *
  124. * @param {String} data to send
  125. * @param {Function} called upon flush.
  126. * @api private
  127. */
  128. JSONPPolling.prototype.doWrite = function (data, fn) {
  129. var self = this;
  130. if (!this.form) {
  131. var form = document.createElement('form');
  132. var area = document.createElement('textarea');
  133. var id = this.iframeId = 'eio_iframe_' + this.index;
  134. var iframe;
  135. form.className = 'socketio';
  136. form.style.position = 'absolute';
  137. form.style.top = '-1000px';
  138. form.style.left = '-1000px';
  139. form.target = id;
  140. form.method = 'POST';
  141. form.setAttribute('accept-charset', 'utf-8');
  142. area.name = 'd';
  143. form.appendChild(area);
  144. document.body.appendChild(form);
  145. this.form = form;
  146. this.area = area;
  147. }
  148. this.form.action = this.uri();
  149. function complete () {
  150. initIframe();
  151. fn();
  152. }
  153. function initIframe () {
  154. if (self.iframe) {
  155. try {
  156. self.form.removeChild(self.iframe);
  157. } catch (e) {
  158. self.onError('jsonp polling iframe removal error', e);
  159. }
  160. }
  161. try {
  162. // ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
  163. var html = '<iframe src="javascript:0" name="' + self.iframeId + '">';
  164. iframe = document.createElement(html);
  165. } catch (e) {
  166. iframe = document.createElement('iframe');
  167. iframe.name = self.iframeId;
  168. iframe.src = 'javascript:0';
  169. }
  170. iframe.id = self.iframeId;
  171. self.form.appendChild(iframe);
  172. self.iframe = iframe;
  173. }
  174. initIframe();
  175. // escape \n to prevent it from being converted into \r\n by some UAs
  176. // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side
  177. data = data.replace(rEscapedNewline, '\\\n');
  178. this.area.value = data.replace(rNewline, '\\n');
  179. try {
  180. this.form.submit();
  181. } catch (e) {}
  182. if (this.iframe.attachEvent) {
  183. this.iframe.onreadystatechange = function () {
  184. if (self.iframe.readyState === 'complete') {
  185. complete();
  186. }
  187. };
  188. } else {
  189. this.iframe.onload = complete;
  190. }
  191. };