-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
85 lines (74 loc) · 2.77 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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
(function(global) {
var channels = [];
function BroadcastChannel(channel) {
var $this = this;
channel = String(channel);
var id = '$BroadcastChannel$' + channel + '$';
channels[id] = channels[id] || [];
channels[id].push(this);
this._name = channel;
this._id = id;
this._closed = false;
this._mc = new MessageChannel();
this._mc.port1.start();
this._mc.port2.start();
global.addEventListener('storage', function(e) {
if (e.storageArea !== global.localStorage) return;
if (e.newValue == null || e.newValue === '') return;
if (e.key.substring(0, id.length) !== id) return;
var data = JSON.parse(e.newValue);
$this._mc.port2.postMessage(data);
});
}
BroadcastChannel.prototype = {
// BroadcastChannel API
get name() {
return this._name;
},
postMessage: function(message) {
var $this = this;
if (this._closed) {
var e = new Error();
e.name = 'InvalidStateError';
throw e;
}
var value = JSON.stringify(message);
// Broadcast to other contexts via storage events...
var key = this._id + String(Date.now()) + '$' + String(Math.random());
global.localStorage.setItem(key, value);
setTimeout(function() {
global.localStorage.removeItem(key);
}, 500);
// Broadcast to current context via ports
channels[this._id].forEach(function(bc) {
if (bc === $this) return;
bc._mc.port2.postMessage(JSON.parse(value));
});
},
close: function() {
if (this._closed) return;
this._closed = true;
this._mc.port1.close();
this._mc.port2.close();
var index = channels[this._id].indexOf(this);
channels[this._id].splice(index, 1);
},
// EventTarget API
get onmessage() {
return this._mc.port1.onmessage;
},
set onmessage(value) {
this._mc.port1.onmessage = value;
},
addEventListener: function(/*type, listener , useCapture*/) {
return this._mc.port1.addEventListener.apply(this._mc.port1, arguments);
},
removeEventListener: function(/*type, listener , useCapture*/) {
return this._mc.port1.removeEventListener.apply(this._mc.port1, arguments);
},
dispatchEvent: function(/*event*/) {
return this._mc.port1.dispatchEvent.apply(this._mc.port1, arguments);
},
};
global.BroadcastChannel = global.BroadcastChannel || BroadcastChannel;
})(self);