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