| 'use strict'; | 
|   | 
| var random = require('../../utils/random') | 
|   , urlUtils = require('../../utils/url') | 
|   ; | 
|   | 
| var debug = function() {}; | 
| if (process.env.NODE_ENV !== 'production') { | 
|   debug = require('debug')('sockjs-client:sender:jsonp'); | 
| } | 
|   | 
| var form, area; | 
|   | 
| function createIframe(id) { | 
|   debug('createIframe', id); | 
|   try { | 
|     // ie6 dynamic iframes with target="" support (thanks Chris Lambacher) | 
|     return global.document.createElement('<iframe name="' + id + '">'); | 
|   } catch (x) { | 
|     var iframe = global.document.createElement('iframe'); | 
|     iframe.name = id; | 
|     return iframe; | 
|   } | 
| } | 
|   | 
| function createForm() { | 
|   debug('createForm'); | 
|   form = global.document.createElement('form'); | 
|   form.style.display = 'none'; | 
|   form.style.position = 'absolute'; | 
|   form.method = 'POST'; | 
|   form.enctype = 'application/x-www-form-urlencoded'; | 
|   form.acceptCharset = 'UTF-8'; | 
|   | 
|   area = global.document.createElement('textarea'); | 
|   area.name = 'd'; | 
|   form.appendChild(area); | 
|   | 
|   global.document.body.appendChild(form); | 
| } | 
|   | 
| module.exports = function(url, payload, callback) { | 
|   debug(url, payload); | 
|   if (!form) { | 
|     createForm(); | 
|   } | 
|   var id = 'a' + random.string(8); | 
|   form.target = id; | 
|   form.action = urlUtils.addQuery(urlUtils.addPath(url, '/jsonp_send'), 'i=' + id); | 
|   | 
|   var iframe = createIframe(id); | 
|   iframe.id = id; | 
|   iframe.style.display = 'none'; | 
|   form.appendChild(iframe); | 
|   | 
|   try { | 
|     area.value = payload; | 
|   } catch (e) { | 
|     // seriously broken browsers get here | 
|   } | 
|   form.submit(); | 
|   | 
|   var completed = function(err) { | 
|     debug('completed', id, err); | 
|     if (!iframe.onerror) { | 
|       return; | 
|     } | 
|     iframe.onreadystatechange = iframe.onerror = iframe.onload = null; | 
|     // Opera mini doesn't like if we GC iframe | 
|     // immediately, thus this timeout. | 
|     setTimeout(function() { | 
|       debug('cleaning up', id); | 
|       iframe.parentNode.removeChild(iframe); | 
|       iframe = null; | 
|     }, 500); | 
|     area.value = ''; | 
|     // It is not possible to detect if the iframe succeeded or | 
|     // failed to submit our form. | 
|     callback(err); | 
|   }; | 
|   iframe.onerror = function() { | 
|     debug('onerror', id); | 
|     completed(); | 
|   }; | 
|   iframe.onload = function() { | 
|     debug('onload', id); | 
|     completed(); | 
|   }; | 
|   iframe.onreadystatechange = function(e) { | 
|     debug('onreadystatechange', id, iframe.readyState, e); | 
|     if (iframe.readyState === 'complete') { | 
|       completed(); | 
|     } | 
|   }; | 
|   return function() { | 
|     debug('aborted', id); | 
|     completed(new Error('Aborted')); | 
|   }; | 
| }; |