1
1
2
2
window . postRobot = ( function ( ) {
3
3
4
+ function noop ( ) { }
5
+
6
+ if ( ! window . addEventListener || ! window . postMessage ) {
7
+
8
+ if ( window . console && window . console . warn ) {
9
+ console . warn ( 'Browser does not support window.postMessage' ) ;
10
+ }
11
+
12
+ return {
13
+ message : noop ,
14
+ listen : noop ,
15
+
16
+ req : noop ,
17
+ res : noop ,
18
+
19
+ destroy : noop
20
+ } ;
21
+ }
22
+
4
23
var POST_MESSAGE_REQUEST = 'post_message_request' ;
5
24
var POST_MESSAGE_RESPONSE = 'post_message_response' ;
25
+ var POST_MESSAGE_ACK = 'post_message_ack' ;
6
26
7
27
var POST_MESSAGE_RESPONSE_ACK_SUCCESS = 'success' ;
8
28
var POST_MESSAGE_RESPONSE_ACK_ERROR = 'error' ;
@@ -43,21 +63,54 @@ window.postRobot = (function() {
43
63
var hash = Math . random ( ) . toString ( ) ;
44
64
responseHandlers [ hash ] = options ;
45
65
66
+ options . respond = once ( function ( err , response ) {
67
+ delete responseHandlers [ hash ] ;
68
+ return options . response ( err , response ) ;
69
+ } ) ;
70
+
71
+ if ( ! options . window . postMessage ) {
72
+ return options . respond ( new Error ( 'Target window does not have postMessage handler' ) ) ;
73
+ }
74
+
75
+ if ( options . window . closed ) {
76
+ return options . respond ( new Error ( 'Target window is closed' ) ) ;
77
+ }
78
+
46
79
if ( options . timeout ) {
47
80
setTimeout ( function ( ) {
48
- if ( responseHandlers [ hash ] ) {
49
- var handler = responseHandlers [ hash ] ;
50
- delete responseHandlers [ hash ] ;
51
- return handler . response ( new Error ( 'Post message response timed out after ' + options . timeout + ' ms' ) ) ;
52
- }
81
+ options . respond ( new Error ( 'Post message response timed out after ' + options . timeout + ' ms' ) ) ;
53
82
} , options . timeout ) ;
54
83
}
55
84
56
- return sendMessage ( options . window , {
57
- type : POST_MESSAGE_REQUEST ,
58
- hash : hash ,
59
- name : options . name ,
60
- data : options . data || { }
85
+ try {
86
+ sendMessage ( options . window , {
87
+ type : POST_MESSAGE_REQUEST ,
88
+ hash : hash ,
89
+ name : options . name ,
90
+ data : options . data || { }
91
+ } ) ;
92
+ } catch ( err ) {
93
+ options . respond ( err ) ;
94
+ }
95
+
96
+ setTimeout ( function ( ) {
97
+ if ( ! options . ack ) {
98
+ return options . respond ( new Error ( 'No ack for postMessage' ) ) ;
99
+ }
100
+ } ) ;
101
+ }
102
+
103
+ function quickPostMessageRequest ( window , name , data , callback ) {
104
+
105
+ if ( ! callback ) {
106
+ callback = data ;
107
+ data = { } ;
108
+ }
109
+
110
+ return postMessageRequest ( {
111
+ window : window ,
112
+ name : name ,
113
+ response : callback
61
114
} ) ;
62
115
}
63
116
@@ -76,6 +129,40 @@ window.postRobot = (function() {
76
129
}
77
130
78
131
requestListeners [ options . name ] = options ;
132
+
133
+ if ( options . window ) {
134
+ var interval = setInterval ( function ( ) {
135
+ if ( options . window . closed ) {
136
+ clearInterval ( interval ) ;
137
+ delete requestListeners [ options . name ] ;
138
+
139
+ if ( options . successOnClose ) {
140
+ options . handler ( null , null , noop ) ;
141
+ } else {
142
+ options . handler ( new Error ( 'Post message target window is closed' ) , null , noop ) ;
143
+ }
144
+ }
145
+ } , 50 ) ;
146
+ }
147
+ }
148
+
149
+ function postMessageListenOnce ( options ) {
150
+ return postMessageListen ( options ) ;
151
+ }
152
+
153
+ function quickPostMessageListen ( name , callback ) {
154
+ return postMessageListen ( {
155
+ name : name ,
156
+ handler : callback
157
+ } ) ;
158
+ }
159
+
160
+ function quickPostMessageListenOnce ( name , callback ) {
161
+ return postMessageListen ( {
162
+ name : name ,
163
+ handler : callback ,
164
+ once : true
165
+ } ) ;
79
166
}
80
167
81
168
function postMessageListener ( event ) {
@@ -92,7 +179,17 @@ window.postRobot = (function() {
92
179
return ;
93
180
}
94
181
95
- if ( message . type === POST_MESSAGE_REQUEST ) {
182
+ if ( message . type === POST_MESSAGE_ACK ) {
183
+
184
+ var options = responseHandlers [ message . hash ] ;
185
+
186
+ if ( ! options ) {
187
+ throw new Error ( 'No handler found for post message ack' ) ;
188
+ }
189
+
190
+ options . ack = true ;
191
+
192
+ } else if ( message . type === POST_MESSAGE_REQUEST ) {
96
193
97
194
var successResponse = once ( function successResponse ( response ) {
98
195
return sendMessage ( event . source , {
@@ -114,15 +211,26 @@ window.postRobot = (function() {
114
211
} ) ;
115
212
} ) ;
116
213
117
- if ( ! requestListeners [ message . name ] ) {
214
+ var listener = requestListeners [ message . name ] ;
215
+
216
+ if ( ! listener ) {
118
217
return errorResponse ( new Error ( 'No postmessage request handler for ' + message . name ) ) ;
119
218
}
120
219
220
+ if ( listener . window && listener . window !== window ) {
221
+ return ;
222
+ }
223
+
224
+ sendMessage ( event . source , {
225
+ type : POST_MESSAGE_ACK ,
226
+ hash : message . hash
227
+ } ) ;
228
+
121
229
var result ;
122
230
123
231
try {
124
232
125
- result = requestListeners [ message . name ] . handler ( message . data , function ( err , response ) {
233
+ result = requestListeners [ message . name ] . handler ( null , message . data , function ( err , response ) {
126
234
return err ? errorResponse ( err ) : successResponse ( response ) ;
127
235
} ) ;
128
236
@@ -136,17 +244,16 @@ window.postRobot = (function() {
136
244
137
245
} else if ( message . type === POST_MESSAGE_RESPONSE ) {
138
246
139
- if ( ! responseHandlers [ message . hash ] ) {
140
- return ;
141
- }
142
-
143
247
var handler = responseHandlers [ message . hash ] ;
144
- delete responseHandlers [ message . hash ] ;
248
+
249
+ if ( ! handler ) {
250
+ throw new Error ( 'No handler found for post message response' ) ;
251
+ }
145
252
146
253
if ( message . ack === POST_MESSAGE_RESPONSE_ACK_ERROR ) {
147
- return handler . response ( message . error ) ;
254
+ return handler . respond ( message . error ) ;
148
255
} else if ( message . ack === POST_MESSAGE_RESPONSE_ACK_SUCCESS ) {
149
- return handler . response ( null , message . response ) ;
256
+ return handler . respond ( null , message . response ) ;
150
257
}
151
258
}
152
259
} ;
@@ -160,9 +267,11 @@ window.postRobot = (function() {
160
267
return {
161
268
request : postMessageRequest ,
162
269
listen : postMessageListen ,
163
- destroy : postMessageDestroy
164
- } ;
165
- } ) ( ) ;
166
-
167
270
271
+ send : quickPostMessageRequest ,
272
+ on : quickPostMessageListen ,
273
+ once : quickPostMessageListenOnce ,
168
274
275
+ destroy : postMessageDestroy
276
+ } ;
277
+ } ) ( ) ;
0 commit comments