-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjquery.postmsg.js
100 lines (94 loc) · 3.04 KB
/
jquery.postmsg.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
(function($) {
var _callbacks = {};
var _listeners = {};
var _bound = false;
var _receive = function(e) {
try {
var msg = JSON.parse(e.data);
} catch (ex) {
return;
}
if (!msg.type)
return;
if (msg.type in _callbacks) {
_callbacks[msg.type](msg.data);
delete _callbacks[msg.type];
return;
}
var funcs = _listeners[msg.type] || [];
for (var i=0; i<funcs.length; i++) {
var f = funcs[i];
if (e.origin !== f.origin) {
if (msg.errcb)
$.postmsg.send(e.source, e.origin, e.errcb,
"postmsg wrong origin: " + f.origin);
continue;
}
try {
var rv = f.call(msg.data);
if (msg.okcb)
$.postmsg.send(e.source, e.origin, msg.okcb, rv);
} catch (ex) {
if (msg.errcb)
$.postmsg.send(e.source, e.origin, msg.errcb, ex);
}
}
};
var _init = function() {
if (_bound) return;
if (window.addEventListener) {
window.addEventListener("message", _receive, false);
} else if (window.attachEvent) {
window.attachEvent("onmessage", _receive);
} else {
$.error("Failed to bind postmessage listener");
}
_bound = true;
}
var _makecb = function(json, fn) {
var cb = new Date().getTime().toString(36) + ':';
cb += sjcl.codec.base64.fromBits(sjcl.hash.sha1.hash(json));
_callbacks[cb] = fn;
return cb;
};
$.postmsg = {
send: function(target, origin, type, data, callbacks) {
_init();
var msg = {data:data, type:type};
var base = JSON.stringify(msg);
callbacks = callbacks || {};
if (callbacks.success)
msg.okcb = _makecb(base, callbacks.success);
if (callbacks.error)
msg.errcb = _makecb(base, callbacks.error);
if ('postMessage' in target) {
target.postMessage(JSON.stringify(msg), origin);
} else {
$.error("No postMessage on target");
}
},
listen: function(origin, type, fn) {
_init();
_listeners[type] = _listeners[type] || [];
_listeners[type].push({call:fn, origin:origin});
},
cancel: function(type, fn) {
if (!type) {
_listeners = {}; // Unbind everything
return;
}
if (!fn) {
delete _listeners[type]; // Unbind this type
return;
}
var funcs = _listeners[type];
if (!funcs) return;
var m = _listeners[type] = [];
for (var i=0; i<funcs.length; i++) {
if (funcs[i].fn !== fn) {
m.push(fns[i]);
}
}
}
};
})(jQuery);