Projekt

Obecné

Profil

Stáhnout (2.83 KB) Statistiky
| Větev: | Revize:
1
'use strict';
2

    
3
var urlUtils = require('./utils/url')
4
  , eventUtils = require('./utils/event')
5
  , JSON3 = require('json3')
6
  , FacadeJS = require('./facade')
7
  , InfoIframeReceiver = require('./info-iframe-receiver')
8
  , iframeUtils = require('./utils/iframe')
9
  , loc = require('./location')
10
  ;
11

    
12
var debug = function() {};
13
if (process.env.NODE_ENV !== 'production') {
14
  debug = require('debug')('sockjs-client:iframe-bootstrap');
15
}
16

    
17
module.exports = function(SockJS, availableTransports) {
18
  var transportMap = {};
19
  availableTransports.forEach(function(at) {
20
    if (at.facadeTransport) {
21
      transportMap[at.facadeTransport.transportName] = at.facadeTransport;
22
    }
23
  });
24

    
25
  // hard-coded for the info iframe
26
  // TODO see if we can make this more dynamic
27
  transportMap[InfoIframeReceiver.transportName] = InfoIframeReceiver;
28
  var parentOrigin;
29

    
30
  /* eslint-disable camelcase */
31
  SockJS.bootstrap_iframe = function() {
32
    /* eslint-enable camelcase */
33
    var facade;
34
    iframeUtils.currentWindowId = loc.hash.slice(1);
35
    var onMessage = function(e) {
36
      if (e.source !== parent) {
37
        return;
38
      }
39
      if (typeof parentOrigin === 'undefined') {
40
        parentOrigin = e.origin;
41
      }
42
      if (e.origin !== parentOrigin) {
43
        return;
44
      }
45

    
46
      var iframeMessage;
47
      try {
48
        iframeMessage = JSON3.parse(e.data);
49
      } catch (ignored) {
50
        debug('bad json', e.data);
51
        return;
52
      }
53

    
54
      if (iframeMessage.windowId !== iframeUtils.currentWindowId) {
55
        return;
56
      }
57
      switch (iframeMessage.type) {
58
      case 's':
59
        var p;
60
        try {
61
          p = JSON3.parse(iframeMessage.data);
62
        } catch (ignored) {
63
          debug('bad json', iframeMessage.data);
64
          break;
65
        }
66
        var version = p[0];
67
        var transport = p[1];
68
        var transUrl = p[2];
69
        var baseUrl = p[3];
70
        debug(version, transport, transUrl, baseUrl);
71
        // change this to semver logic
72
        if (version !== SockJS.version) {
73
          throw new Error('Incompatible SockJS! Main site uses:' +
74
                    ' "' + version + '", the iframe:' +
75
                    ' "' + SockJS.version + '".');
76
        }
77

    
78
        if (!urlUtils.isOriginEqual(transUrl, loc.href) ||
79
            !urlUtils.isOriginEqual(baseUrl, loc.href)) {
80
          throw new Error('Can\'t connect to different domain from within an ' +
81
                    'iframe. (' + loc.href + ', ' + transUrl + ', ' + baseUrl + ')');
82
        }
83
        facade = new FacadeJS(new transportMap[transport](transUrl, baseUrl));
84
        break;
85
      case 'm':
86
        facade._send(iframeMessage.data);
87
        break;
88
      case 'c':
89
        if (facade) {
90
          facade._close();
91
        }
92
        facade = null;
93
        break;
94
      }
95
    };
96

    
97
    eventUtils.attachEvent('message', onMessage);
98

    
99
    // Start
100
    iframeUtils.postMessage('s');
101
  };
102
};
(3-3/12)