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