Files: e57ae82e4ad29ce90e5085f85c8f351e54f5231e / index.js
1926 bytesRaw
1 | function fixJSON(key, value) { |
2 | if (value instanceof Error) return { |
3 | message: value.message, |
4 | stack: value.stack, |
5 | name: value.name, |
6 | code: value.code, |
7 | } |
8 | return value |
9 | } |
10 | |
11 | function isOriginCompatible(a, b) { |
12 | return !a || a === '*' || a.slice(0, b.length) === b |
13 | } |
14 | |
15 | var cmds = { |
16 | read: 'r', |
17 | readEnd: 'R', |
18 | next: 'n', |
19 | nextEnd: 'N', |
20 | } |
21 | |
22 | module.exports = function (win, origin) { |
23 | var _cb, _msg |
24 | |
25 | if(origin && origin[0] === '/') { |
26 | origin = location.origin + origin |
27 | } |
28 | |
29 | function post(cmd, data) { |
30 | var msg = cmd + data |
31 | if (!win) _msg = msg |
32 | else win.postMessage(msg, origin || '*') |
33 | } |
34 | |
35 | function gotWin(_win) { |
36 | win = _win |
37 | if (_msg) { |
38 | var msg = _msg |
39 | _msg = null |
40 | post(msg) |
41 | } |
42 | } |
43 | |
44 | return function (read) { |
45 | function onMessage(e) { |
46 | if(isOriginCompatible(origin, e.origin)) { |
47 | if(!win) gotWin(e.source) |
48 | if(!origin) origin = e.origin |
49 | switch (e.data[0]) { |
50 | case cmds.read: return onRead(null) |
51 | case cmds.readEnd: return onRead(JSON.parse(e.data.substr(1))) |
52 | case cmds.next: return onNext(null, e.data.substr(1)) |
53 | case cmds.nextEnd: return onNext(JSON.parse(e.data.substr(1))) |
54 | } |
55 | } |
56 | } |
57 | |
58 | function onRead(end) { |
59 | read(end, function (end, data) { |
60 | if (end) post(cmds.nextEnd, JSON.stringify(end, fixJSON)) |
61 | else post(cmds.next, data) |
62 | }) |
63 | } |
64 | |
65 | function onNext(end, data) { |
66 | if (end) window.removeEventListener('message', onMessage, false) |
67 | if (!_cb) return console.error('unexpected data', end, data) |
68 | var cb = _cb |
69 | _cb = null |
70 | return cb(end, data) |
71 | } |
72 | |
73 | window.addEventListener('message', onMessage, false) |
74 | |
75 | return function (end, cb) { |
76 | if(_cb) return cb(new Error('read too soon')) |
77 | _cb = cb |
78 | if (end) post(cmds.readEnd, JSON.stringify(end, fixJSON)) |
79 | else post(cmds.read) |
80 | } |
81 | } |
82 | } |
83 |
Built with git-ssb-web