'use strict'; var urlUtils = require('./utils/url') , eventUtils = require('./utils/event') , JSON3 = require('json3') , FacadeJS = require('./facade') , InfoIframeReceiver = require('./info-iframe-receiver') , iframeUtils = require('./utils/iframe') , loc = require('./location') ; var debug = function() {}; if (process.env.NODE_ENV !== 'production') { debug = require('debug')('sockjs-client:iframe-bootstrap'); } module.exports = function(SockJS, availableTransports) { var transportMap = {}; availableTransports.forEach(function(at) { if (at.facadeTransport) { transportMap[at.facadeTransport.transportName] = at.facadeTransport; } }); // hard-coded for the info iframe // TODO see if we can make this more dynamic transportMap[InfoIframeReceiver.transportName] = InfoIframeReceiver; var parentOrigin; /* eslint-disable camelcase */ SockJS.bootstrap_iframe = function() { /* eslint-enable camelcase */ var facade; iframeUtils.currentWindowId = loc.hash.slice(1); var onMessage = function(e) { if (e.source !== parent) { return; } if (typeof parentOrigin === 'undefined') { parentOrigin = e.origin; } if (e.origin !== parentOrigin) { return; } var iframeMessage; try { iframeMessage = JSON3.parse(e.data); } catch (ignored) { debug('bad json', e.data); return; } if (iframeMessage.windowId !== iframeUtils.currentWindowId) { return; } switch (iframeMessage.type) { case 's': var p; try { p = JSON3.parse(iframeMessage.data); } catch (ignored) { debug('bad json', iframeMessage.data); break; } var version = p[0]; var transport = p[1]; var transUrl = p[2]; var baseUrl = p[3]; debug(version, transport, transUrl, baseUrl); // change this to semver logic if (version !== SockJS.version) { throw new Error('Incompatible SockJS! Main site uses:' + ' "' + version + '", the iframe:' + ' "' + SockJS.version + '".'); } if (!urlUtils.isOriginEqual(transUrl, loc.href) || !urlUtils.isOriginEqual(baseUrl, loc.href)) { throw new Error('Can\'t connect to different domain from within an ' + 'iframe. (' + loc.href + ', ' + transUrl + ', ' + baseUrl + ')'); } facade = new FacadeJS(new transportMap[transport](transUrl, baseUrl)); break; case 'm': facade._send(iframeMessage.data); break; case 'c': if (facade) { facade._close(); } facade = null; break; } }; eventUtils.attachEvent('message', onMessage); // Start iframeUtils.postMessage('s'); }; };