-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
96 lines (81 loc) · 2.41 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
86
87
88
89
90
91
92
93
94
95
96
module.exports = Postie
var EventEmitter = require('events').EventEmitter
var inherits = require('inherits')
var postMessage = require('./postmessage')
function Postie (target, origin) {
if (!(this instanceof Postie)) return new Postie(target, origin)
// '*' is a wildcard origin
if (origin == null) origin = '*'
EventEmitter.call(this)
this.target = target
this.origin = origin
this.listen()
}
inherits(Postie, EventEmitter)
Postie.prototype.post = post
Postie.prototype.listen = listen
Postie.prototype.stopListening = stopListening
Postie.prototype.handleMessage = handleMessage
Postie.prototype.unpack = unpack
Postie.prototype.pack = pack
// Get the channel and arguments and send it to the target
// Channel is the event that the other side will be listening for
function post (channel) {
var args = Array.prototype.slice.call(arguments, 1)
var packed = this.pack(channel, args)
postMessage(this.target, packed, this.origin)
}
// Listens in a cross-browser fashion. When postmessage isn't available
// we'll either have to change listen or fake message events somehow.
function listen () {
var _this = this
this.handler = function () {
_this.handleMessage.apply(_this, arguments)
}
if (window.addEventListener) {
window.addEventListener('message', this.handler)
}
else {
window.attachEvent('onmessage', this.handler)
}
}
// Cleans up event listeners
function stopListening () {
if (window.removeEventListener) {
window.removeEventListener('message', this.handler)
}
else {
window.detachEvent('onmessage', this.handler)
}
}
// Unpacks and emits
function handleMessage (ev) {
var unpacked = this.unpack(ev.data)
if (unpacked) {
var args = [ unpacked.channel ]
args.push.apply(args, unpacked.args)
this.emit.apply(this, args)
}
}
// Takes a message data string and deserialises it
function unpack (data) {
// We don't control all message events, they won't always be JSON
try {
var unpacked = JSON.parse(data)
if (unpacked.__postie) return unpacked.__postie
return false
}
catch (e) {
return false
}
}
// Takes a channel and the arguments to emit with and serialises it
// for transmission
function pack (channel, args) {
return JSON.stringify({
__postie: {
channel: channel
, args: args
}
})
}