-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
69 lines (60 loc) · 1.97 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
var has = require('has');
var isarray = require('isarray');
var VERSION = '1.0.0';
module.exports = RPC;
function RPC (src, dst, origin, methods) {
if (!(this instanceof RPC)) return new RPC(src, dst, origin, methods);
var self = this;
this.src = src;
this.dst = dst;
var uorigin = new URL(origin);
this.origin = uorigin.protocol + '//' + uorigin.host;
this._methods = methods || {};
this._sequence = 0;
this._callbacks = {};
this.src.addEventListener('message', function (ev) {
if (ev.origin !== self.origin) return;
if (!ev.data || typeof ev.data !== 'object') return;
if (ev.data.protocol !== 'frame-rpc') return;
if (!isarray(ev.data.arguments)) return;
self._handle(ev.data);
});
}
RPC.prototype.call = function (method) {
var args = [].slice.call(arguments, 1);
return this.apply(method, args);
};
RPC.prototype.apply = function (method, args) {
var seq = this._sequence ++;
if (typeof args[args.length - 1] === 'function') {
this._callbacks[seq] = args[args.length - 1];
args = args.slice(0, -1);
}
this.dst.postMessage({
protocol: 'frame-rpc',
version: VERSION,
sequence: seq,
method: method,
arguments: args
}, this.origin);
};
RPC.prototype._handle = function (msg) {
var self = this;
if (has(msg, 'method')) {
if (!has(this._methods, msg.method)) return;
var args = msg.arguments.concat(function () {
self.dst.postMessage({
protocol: 'frame-rpc',
version: VERSION,
response: msg.sequence,
arguments: [].slice.call(arguments)
}, self.origin);
});
this._methods[msg.method].apply(this._methods, args);
}
else if (has(msg, 'response')) {
var cb = this._callbacks[msg.response];
delete this._callbacks[msg.response];
if (cb) cb.apply(null, msg.arguments);
}
};