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};