102 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| var urlUtils = require('./utils/url')
 | |
|   , eventUtils = require('./utils/event')
 | |
|   , 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 = JSON.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 = JSON.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');
 | |
|   };
 | |
| };
 | 
