6 var Polling = require('./polling')
7 , util = require('../util');
13 module.exports = JSONPPolling;
19 var global = 'undefined' != typeof window ? window : global;
22 * Cached regular expressions.
28 * Global JSONP callbacks.
46 * JSONP Polling constructor.
48 * @param {Object} opts.
52 function JSONPPolling (opts) {
53 Polling.call(this, opts);
55 // define global callbacks array if not present
56 // we do this here (lazily) to avoid unneeded global pollution
58 // we need to consider multiple engines in the same page
59 if (!global.___eio) global.___eio = [];
60 callbacks = global.___eio;
63 // callback identifier
64 this.index = callbacks.length;
66 // add callback to jsonp global
68 callbacks.push(function (msg) {
72 // append to query string
73 this.query.j = this.index;
77 * Inherits from Polling.
80 util.inherits(JSONPPolling, Polling);
88 JSONPPolling.prototype.doOpen = function () {
90 util.defer(function () {
91 Polling.prototype.doOpen.call(self);
101 JSONPPolling.prototype.doClose = function () {
103 this.script.parentNode.removeChild(this.script);
108 this.form.parentNode.removeChild(this.form);
112 Polling.prototype.doClose.call(this);
116 * Starts a poll cycle.
121 JSONPPolling.prototype.doPoll = function () {
122 var script = document.createElement('script');
125 this.script.parentNode.removeChild(this.script);
130 script.src = this.uri();
132 var insertAt = document.getElementsByTagName('script')[0];
133 insertAt.parentNode.insertBefore(script, insertAt);
134 this.script = script;
137 setTimeout(function () {
138 var iframe = document.createElement('iframe');
139 document.body.appendChild(iframe);
140 document.body.removeChild(iframe);
146 * Writes with a hidden iframe.
148 * @param {String} data to send
149 * @param {Function} called upon flush.
153 JSONPPolling.prototype.doWrite = function (data, fn) {
157 var form = document.createElement('form')
158 , area = document.createElement('textarea')
159 , id = this.iframeId = 'eio_iframe_' + this.index
162 form.className = 'socketio';
163 form.style.position = 'absolute';
164 form.style.top = '-1000px';
165 form.style.left = '-1000px';
167 form.method = 'POST';
168 form.setAttribute('accept-charset', 'utf-8');
170 form.appendChild(area);
171 document.body.appendChild(form);
177 this.form.action = this.uri();
179 function complete () {
184 function initIframe () {
186 self.form.removeChild(self.iframe);
190 // ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
191 iframe = document.createElement('<iframe name="'+ self.iframeId +'">');
193 iframe = document.createElement('iframe');
194 iframe.name = self.iframeId;
197 iframe.id = self.iframeId;
199 self.form.appendChild(iframe);
200 self.iframe = iframe;
205 // escape \n to prevent it from being converted into \r\n by some UAs
206 this.area.value = data.replace(rNewline, '\\n');
212 if (this.iframe.attachEvent) {
213 this.iframe.onreadystatechange = function(){
214 if (self.iframe.readyState == 'complete') {
219 this.iframe.onload = complete;