-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhhConnect.js
119 lines (95 loc) · 3.55 KB
/
hhConnect.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
module.exports = function(userConfig){
// If false or invalid window, return a dummy object (So it wont break apps)
if (!userConfig.target)
{
console.info('[hhConnect] No target window found!');
return { on: function(){}, emit: function(){}, call: function(){}, bind: function(){} }
}
// Settings for this instance
var config = {
target: userConfig.target,
cbReady: userConfig.onReady || function(){},
namespace: userConfig.namespace || 'HH',
permission: userConfig.permission || '*',
instance: Math.random().toString(36).substr(2, 9),
messageID: 0
}
// Will store all the callbacks for this instance
var cbs = {
event: {},
method: {},
message: {},
}
// HELPER: Generate a new messageID for communications
var nextMessageID = function()
{
return config.instance+'-'+(config.messageID+++1);
}
// Helper: Send the message using an RPC fashion
var sendMessage = function(name, data, id) {
//console.log('sendMessage', [name, data, id])
config.target.postMessage({
namespace: config.namespace,
id: id || nextMessageID(),
name: name,
data: data
}, config.permission);
}
// Incoming messages handler
window.addEventListener("message", function(event){
/*
// Check origin policy
if (event.origin !== '*' && event.origin !== 'null' && event.origin !== config.permission)
return console.warn('[hhConnect] Post Forbiden: ' + event.origin + ' != ' + config.permission);
*/
var request = event.data;
if (request.namespace !== config.namespace)
return;
if (request.name == '__ready')
{
if (request.data == 'ping!')
sendMessage('__ready', 'pong!')
config.cbReady();
return;
}
if (cbs.method[request.name])
cbs.method[request.name]( request.data, function(error, data){
sendMessage('_callback_'+request.name, {error: error, data: data}, request.id)
})
// Any METHOD callback for this ID? Call it and delete it
if (cbs.message[request.id])
{
cbs.message[request.id](request.data.error, request.data.data)
delete cbs.message[request.id]
}
// Any EVENT with this name?
if (cbs.event[request.name])
cbs.event[request.name](request.data);
// Any catch-all EVENT? also send there
if (cbs.event['*'] && request.name.indexOf('__event__') > -1)
cbs.event['*'](request.name.substring(9), request.data);
}, false);
setTimeout(function() {
sendMessage('__ready', 'ping!')
}, 0);
return {
// ######## EVENTS ########
on: function(eventName, eventCB){
cbs.event['__event__'+eventName] = eventCB
},
emit: function(eventName, eventData){
sendMessage('__event__'+eventName, eventData)
},
// ######## METHODS ########
bind: function(methodName, methodFunction){
cbs.method['_method_'+methodName] = methodFunction
},
call: function(methodName, methodParams, methodCB){
var messageID = nextMessageID();
// Save this callback to call when this ID returns
if (methodCB)
cbs.message[messageID] = methodCB;
sendMessage('_method_'+methodName, methodParams, messageID);
}
}
}