You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							186 lines
						
					
					
						
							4.9 KiB
						
					
					
				
			
		
		
	
	
							186 lines
						
					
					
						
							4.9 KiB
						
					
					
				'use strict'; | 
						|
 | 
						|
var eventUtils = require('./event') | 
						|
  , JSON3 = require('json3') | 
						|
  , browser = require('./browser') | 
						|
  ; | 
						|
 | 
						|
var debug = function() {}; | 
						|
if (process.env.NODE_ENV !== 'production') { | 
						|
  debug = require('debug')('sockjs-client:utils:iframe'); | 
						|
} | 
						|
 | 
						|
module.exports = { | 
						|
  WPrefix: '_jp' | 
						|
, currentWindowId: null | 
						|
 | 
						|
, polluteGlobalNamespace: function() { | 
						|
    if (!(module.exports.WPrefix in global)) { | 
						|
      global[module.exports.WPrefix] = {}; | 
						|
    } | 
						|
  } | 
						|
 | 
						|
, postMessage: function(type, data) { | 
						|
    if (global.parent !== global) { | 
						|
      global.parent.postMessage(JSON3.stringify({ | 
						|
        windowId: module.exports.currentWindowId | 
						|
      , type: type | 
						|
      , data: data || '' | 
						|
      }), '*'); | 
						|
    } else { | 
						|
      debug('Cannot postMessage, no parent window.', type, data); | 
						|
    } | 
						|
  } | 
						|
 | 
						|
, createIframe: function(iframeUrl, errorCallback) { | 
						|
    var iframe = global.document.createElement('iframe'); | 
						|
    var tref, unloadRef; | 
						|
    var unattach = function() { | 
						|
      debug('unattach'); | 
						|
      clearTimeout(tref); | 
						|
      // Explorer had problems with that. | 
						|
      try { | 
						|
        iframe.onload = null; | 
						|
      } catch (x) { | 
						|
        // intentionally empty | 
						|
      } | 
						|
      iframe.onerror = null; | 
						|
    }; | 
						|
    var cleanup = function() { | 
						|
      debug('cleanup'); | 
						|
      if (iframe) { | 
						|
        unattach(); | 
						|
        // This timeout makes chrome fire onbeforeunload event | 
						|
        // within iframe. Without the timeout it goes straight to | 
						|
        // onunload. | 
						|
        setTimeout(function() { | 
						|
          if (iframe) { | 
						|
            iframe.parentNode.removeChild(iframe); | 
						|
          } | 
						|
          iframe = null; | 
						|
        }, 0); | 
						|
        eventUtils.unloadDel(unloadRef); | 
						|
      } | 
						|
    }; | 
						|
    var onerror = function(err) { | 
						|
      debug('onerror', err); | 
						|
      if (iframe) { | 
						|
        cleanup(); | 
						|
        errorCallback(err); | 
						|
      } | 
						|
    }; | 
						|
    var post = function(msg, origin) { | 
						|
      debug('post', msg, origin); | 
						|
      setTimeout(function() { | 
						|
        try { | 
						|
          // When the iframe is not loaded, IE raises an exception | 
						|
          // on 'contentWindow'. | 
						|
          if (iframe && iframe.contentWindow) { | 
						|
            iframe.contentWindow.postMessage(msg, origin); | 
						|
          } | 
						|
        } catch (x) { | 
						|
          // intentionally empty | 
						|
        } | 
						|
      }, 0); | 
						|
    }; | 
						|
 | 
						|
    iframe.src = iframeUrl; | 
						|
    iframe.style.display = 'none'; | 
						|
    iframe.style.position = 'absolute'; | 
						|
    iframe.onerror = function() { | 
						|
      onerror('onerror'); | 
						|
    }; | 
						|
    iframe.onload = function() { | 
						|
      debug('onload'); | 
						|
      // `onload` is triggered before scripts on the iframe are | 
						|
      // executed. Give it few seconds to actually load stuff. | 
						|
      clearTimeout(tref); | 
						|
      tref = setTimeout(function() { | 
						|
        onerror('onload timeout'); | 
						|
      }, 2000); | 
						|
    }; | 
						|
    global.document.body.appendChild(iframe); | 
						|
    tref = setTimeout(function() { | 
						|
      onerror('timeout'); | 
						|
    }, 15000); | 
						|
    unloadRef = eventUtils.unloadAdd(cleanup); | 
						|
    return { | 
						|
      post: post | 
						|
    , cleanup: cleanup | 
						|
    , loaded: unattach | 
						|
    }; | 
						|
  } | 
						|
 | 
						|
/* eslint no-undef: "off", new-cap: "off" */ | 
						|
, createHtmlfile: function(iframeUrl, errorCallback) { | 
						|
    var axo = ['Active'].concat('Object').join('X'); | 
						|
    var doc = new global[axo]('htmlfile'); | 
						|
    var tref, unloadRef; | 
						|
    var iframe; | 
						|
    var unattach = function() { | 
						|
      clearTimeout(tref); | 
						|
      iframe.onerror = null; | 
						|
    }; | 
						|
    var cleanup = function() { | 
						|
      if (doc) { | 
						|
        unattach(); | 
						|
        eventUtils.unloadDel(unloadRef); | 
						|
        iframe.parentNode.removeChild(iframe); | 
						|
        iframe = doc = null; | 
						|
        CollectGarbage(); | 
						|
      } | 
						|
    }; | 
						|
    var onerror = function(r) { | 
						|
      debug('onerror', r); | 
						|
      if (doc) { | 
						|
        cleanup(); | 
						|
        errorCallback(r); | 
						|
      } | 
						|
    }; | 
						|
    var post = function(msg, origin) { | 
						|
      try { | 
						|
        // When the iframe is not loaded, IE raises an exception | 
						|
        // on 'contentWindow'. | 
						|
        setTimeout(function() { | 
						|
          if (iframe && iframe.contentWindow) { | 
						|
              iframe.contentWindow.postMessage(msg, origin); | 
						|
          } | 
						|
        }, 0); | 
						|
      } catch (x) { | 
						|
        // intentionally empty | 
						|
      } | 
						|
    }; | 
						|
 | 
						|
    doc.open(); | 
						|
    doc.write('<html><s' + 'cript>' + | 
						|
              'document.domain="' + global.document.domain + '";' + | 
						|
              '</s' + 'cript></html>'); | 
						|
    doc.close(); | 
						|
    doc.parentWindow[module.exports.WPrefix] = global[module.exports.WPrefix]; | 
						|
    var c = doc.createElement('div'); | 
						|
    doc.body.appendChild(c); | 
						|
    iframe = doc.createElement('iframe'); | 
						|
    c.appendChild(iframe); | 
						|
    iframe.src = iframeUrl; | 
						|
    iframe.onerror = function() { | 
						|
      onerror('onerror'); | 
						|
    }; | 
						|
    tref = setTimeout(function() { | 
						|
      onerror('timeout'); | 
						|
    }, 15000); | 
						|
    unloadRef = eventUtils.unloadAdd(cleanup); | 
						|
    return { | 
						|
      post: post | 
						|
    , cleanup: cleanup | 
						|
    , loaded: unattach | 
						|
    }; | 
						|
  } | 
						|
}; | 
						|
 | 
						|
module.exports.iframeEnabled = false; | 
						|
if (global.document) { | 
						|
  // postMessage misbehaves in konqueror 4.6.5 - the messages are delivered with | 
						|
  // huge delay, or not at all. | 
						|
  module.exports.iframeEnabled = (typeof global.postMessage === 'function' || | 
						|
    typeof global.postMessage === 'object') && (!browser.isKonqueror()); | 
						|
}
 | 
						|
 |